<commit_before>package stores

import (
	"sync"

	"github.com/davelondon/kerr"
	"golang.org/x/net/context"
	"kego.io/editor/client/actions"
	"kego.io/editor/client/models"
	"kego.io/flux"
	"kego.io/process/validate"
	"kego.io/system"
	"kego.io/system/node"
)

type RuleStore struct {
	*flux.Store
	ctx context.Context
	app *App

	m     *sync.RWMutex
	rules map[*node.Node]map[*node.Node][]system.RuleInterface
}

type ruleNotif string

func (b ruleNotif) IsNotif() {}

//const (
//RuleChanged ruleNotif = "RuleChanged"
//)

func NewRuleStore(ctx context.Context) *RuleStore {
	s := &RuleStore{
		Store: &flux.Store{},
		ctx:   ctx,
		app:   FromContext(ctx),
		m:     &sync.RWMutex{},
		rules: map[*node.Node]map[*node.Node][]system.RuleInterface{},
	}
	s.Init(s)
	return s
}

func (s *RuleStore) Get(r *node.Node, n *node.Node) []system.RuleInterface {
	s.m.RLock()
	defer s.m.RUnlock()
	root, ok := s.rules[r]
	if !ok {
		return nil
	}
	rules, ok := root[n]
	if !ok {
		return nil
	}
	return rules
}

func (s *RuleStore) Handle(payload *flux.Payload) bool {
	switch action := payload.Action.(type) {
	case *actions.InitialState:
		payload.Wait(s.app.Package, s.app.Types)
		changes := s.build(s.app.Package.Node())
		s.validateNodes(changes)
		for _, t := range s.app.Types.All() {
			changes := s.build(t)
			s.validateNodes(changes)
		}
	case *actions.LoadSourceSuccess:
		payload.Wait(s.app.Branches)
		ni, ok := action.Branch.Contents.(models.NodeContentsInterface)
		if !ok {
			break
		}
		n := ni.GetNode()
		changes := s.build(n)
		s.validateNodes(changes)
	case *actions.EditorValueChange500ms:
		changes := s.build(action.Editor.Node.Root())
		s.validateNodes(changes)
	}
	return true
}

func (s *RuleStore) validateNodes(changes []*node.Node) {
	for _, n := range changes {
		m := s.app.Nodes.Get(n)<commit_msg>Validators re-validate on node mutation events. Problems created by multiple notifications.<commit_after>package stores

import (
	"sync"

	"github.com/davelondon/kerr"
	"golang.org/x/net/context"
	"kego.io/editor/client/actions"
	"kego.io/editor/client/models"
	"kego.io/flux"
	"kego.io/process/validate"
	"kego.io/system"
	"kego.io/system/node"
)

type RuleStore struct {
	*flux.Store
	ctx context.Context
	app *App

	m     *sync.RWMutex
	rules map[*node.Node]map[*node.Node][]system.RuleInterface
}

type ruleNotif string

func (b ruleNotif) IsNotif() {}

//const (
//RuleChanged ruleNotif = "RuleChanged"
//)

func NewRuleStore(ctx context.Context) *RuleStore {
	s := &RuleStore{
		Store: &flux.Store{},
		ctx:   ctx,
		app:   FromContext(ctx),
		m:     &sync.RWMutex{},
		rules: map[*node.Node]map[*node.Node][]system.RuleInterface{},
	}
	s.Init(s)
	return s
}

func (s *RuleStore) Get(r *node.Node, n *node.Node) []system.RuleInterface {
	s.m.RLock()
	defer s.m.RUnlock()
	root, ok := s.rules[r]
	if !ok {
		return nil
	}
	rules, ok := root[n]
	if !ok {
		return nil
	}
	return rules
}

func (s *RuleStore) Handle(payload *flux.Payload) bool {
	switch action := payload.Action.(type) {
	case *actions.InitialState:
		payload.Wait(s.app.Package, s.app.Types)
		s.validateNodes(s.build(s.app.Package.Node()))
		for _, t := range s.app.Types.All() {
			s.validateNodes(s.build(t))
		}
	case *actions.LoadSourceSuccess:
		payload.Wait(s.app.Branches)
		ni, ok := action.Branch.Contents.(models.NodeContentsInterface)
		if !ok {
			break
		}
		n := ni.GetNode()
		s.validateNodes(s.build(n))
	case *actions.EditorValueChange500ms:
		s.validateNodes(s.build(action.Editor.Node.Root()))
	case *actions.ArrayOrder:
		payload.Wait(s.app.Nodes)
		s.validateNodes(s.build(action.Model.Node.Root()))
	case *actions.DeleteNode:
		payload.Wait(s.app.Nodes)
		s.validateNodes(s.build(action.Node.Root()))
	case *actions.InitializeNode:
		payload.Wait(s.app.Nodes)
		s.validateNodes(s.build(action.Node.Root()))
	}
	return true
}

func (s *RuleStore) validateNodes(changes []*node.Node) {
	for _, n := range changes {
		m := s.app.Nodes.Get(n)
{'fraction_non_alphanumeric': 0.16426585797321203, 'fraction_numerical': 0.001516300227445034, 'mean_word_length': 3.929016189290162, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5910134', 'n_tokens_mistral': 1614, 'n_tokens_neox': 1534, 'n_words': 285}