@manifesto-ai/core 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +434 -0
- package/dist/dag/graph.d.ts +62 -0
- package/dist/dag/graph.d.ts.map +1 -0
- package/dist/dag/graph.js +244 -0
- package/dist/dag/graph.js.map +1 -0
- package/dist/dag/index.d.ts +4 -0
- package/dist/dag/index.d.ts.map +1 -0
- package/dist/dag/index.js +4 -0
- package/dist/dag/index.js.map +1 -0
- package/dist/dag/propagation.d.ts +58 -0
- package/dist/dag/propagation.d.ts.map +1 -0
- package/dist/dag/propagation.js +224 -0
- package/dist/dag/propagation.js.map +1 -0
- package/dist/dag/topological.d.ts +33 -0
- package/dist/dag/topological.d.ts.map +1 -0
- package/dist/dag/topological.js +173 -0
- package/dist/dag/topological.js.map +1 -0
- package/dist/domain/define.d.ts +82 -0
- package/dist/domain/define.d.ts.map +1 -0
- package/dist/domain/define.js +91 -0
- package/dist/domain/define.js.map +1 -0
- package/dist/domain/index.d.ts +4 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/index.js +4 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/domain/types.d.ts +203 -0
- package/dist/domain/types.d.ts.map +1 -0
- package/dist/domain/types.js +2 -0
- package/dist/domain/types.js.map +1 -0
- package/dist/domain/validate.d.ts +17 -0
- package/dist/domain/validate.d.ts.map +1 -0
- package/dist/domain/validate.js +204 -0
- package/dist/domain/validate.js.map +1 -0
- package/dist/effect/index.d.ts +4 -0
- package/dist/effect/index.d.ts.map +1 -0
- package/dist/effect/index.js +4 -0
- package/dist/effect/index.js.map +1 -0
- package/dist/effect/result.d.ts +100 -0
- package/dist/effect/result.d.ts.map +1 -0
- package/dist/effect/result.js +163 -0
- package/dist/effect/result.js.map +1 -0
- package/dist/effect/runner.d.ts +98 -0
- package/dist/effect/runner.d.ts.map +1 -0
- package/dist/effect/runner.js +321 -0
- package/dist/effect/runner.js.map +1 -0
- package/dist/effect/types.d.ts +169 -0
- package/dist/effect/types.d.ts.map +1 -0
- package/dist/effect/types.js +28 -0
- package/dist/effect/types.js.map +1 -0
- package/dist/expression/analyzer.d.ts +42 -0
- package/dist/expression/analyzer.d.ts.map +1 -0
- package/dist/expression/analyzer.js +166 -0
- package/dist/expression/analyzer.js.map +1 -0
- package/dist/expression/evaluator.d.ts +16 -0
- package/dist/expression/evaluator.d.ts.map +1 -0
- package/dist/expression/evaluator.js +382 -0
- package/dist/expression/evaluator.js.map +1 -0
- package/dist/expression/index.d.ts +5 -0
- package/dist/expression/index.d.ts.map +1 -0
- package/dist/expression/index.js +5 -0
- package/dist/expression/index.js.map +1 -0
- package/dist/expression/parser.d.ts +37 -0
- package/dist/expression/parser.d.ts.map +1 -0
- package/dist/expression/parser.js +201 -0
- package/dist/expression/parser.js.map +1 -0
- package/dist/expression/types.d.ts +123 -0
- package/dist/expression/types.d.ts.map +1 -0
- package/dist/expression/types.js +10 -0
- package/dist/expression/types.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/policy/field-policy.d.ts +63 -0
- package/dist/policy/field-policy.d.ts.map +1 -0
- package/dist/policy/field-policy.js +138 -0
- package/dist/policy/field-policy.js.map +1 -0
- package/dist/policy/index.d.ts +3 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +3 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/precondition.d.ts +58 -0
- package/dist/policy/precondition.d.ts.map +1 -0
- package/dist/policy/precondition.js +115 -0
- package/dist/policy/precondition.js.map +1 -0
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +4 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/runtime.d.ts +94 -0
- package/dist/runtime/runtime.d.ts.map +1 -0
- package/dist/runtime/runtime.js +294 -0
- package/dist/runtime/runtime.js.map +1 -0
- package/dist/runtime/snapshot.d.ts +39 -0
- package/dist/runtime/snapshot.d.ts.map +1 -0
- package/dist/runtime/snapshot.js +264 -0
- package/dist/runtime/snapshot.js.map +1 -0
- package/dist/runtime/subscription.d.ts +82 -0
- package/dist/runtime/subscription.d.ts.map +1 -0
- package/dist/runtime/subscription.js +222 -0
- package/dist/runtime/subscription.js.map +1 -0
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +3 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/integration.d.ts +89 -0
- package/dist/schema/integration.d.ts.map +1 -0
- package/dist/schema/integration.js +171 -0
- package/dist/schema/integration.js.map +1 -0
- package/dist/schema/validation.d.ts +51 -0
- package/dist/schema/validation.d.ts.map +1 -0
- package/dist/schema/validation.js +212 -0
- package/dist/schema/validation.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { extractPaths } from '../expression/parser.js';
|
|
2
|
+
/**
|
|
3
|
+
* 도메인에서 의존성 그래프 구축
|
|
4
|
+
*/
|
|
5
|
+
export function buildDependencyGraph(domain) {
|
|
6
|
+
const nodes = new Map();
|
|
7
|
+
const dependencies = new Map();
|
|
8
|
+
const dependents = new Map();
|
|
9
|
+
// 1. Source 노드 추가
|
|
10
|
+
for (const [path, definition] of Object.entries(domain.paths.sources)) {
|
|
11
|
+
nodes.set(path, { kind: 'source', path, definition });
|
|
12
|
+
dependencies.set(path, new Set());
|
|
13
|
+
if (!dependents.has(path)) {
|
|
14
|
+
dependents.set(path, new Set());
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// 2. Derived 노드 추가
|
|
18
|
+
for (const [path, definition] of Object.entries(domain.paths.derived)) {
|
|
19
|
+
nodes.set(path, { kind: 'derived', path, definition });
|
|
20
|
+
// Expression에서 의존성 추출
|
|
21
|
+
const deps = new Set(definition.deps);
|
|
22
|
+
const exprDeps = extractPaths(definition.expr);
|
|
23
|
+
for (const dep of exprDeps) {
|
|
24
|
+
if (!dep.startsWith('$')) {
|
|
25
|
+
deps.add(dep);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
dependencies.set(path, deps);
|
|
29
|
+
// 역방향 엣지 추가
|
|
30
|
+
for (const dep of deps) {
|
|
31
|
+
if (!dependents.has(dep)) {
|
|
32
|
+
dependents.set(dep, new Set());
|
|
33
|
+
}
|
|
34
|
+
dependents.get(dep).add(path);
|
|
35
|
+
}
|
|
36
|
+
if (!dependents.has(path)) {
|
|
37
|
+
dependents.set(path, new Set());
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// 3. Async 노드 추가
|
|
41
|
+
for (const [path, definition] of Object.entries(domain.paths.async)) {
|
|
42
|
+
nodes.set(path, { kind: 'async', path, definition });
|
|
43
|
+
// Async의 의존성
|
|
44
|
+
const deps = new Set(definition.deps);
|
|
45
|
+
if (definition.condition) {
|
|
46
|
+
const condDeps = extractPaths(definition.condition);
|
|
47
|
+
for (const dep of condDeps) {
|
|
48
|
+
if (!dep.startsWith('$')) {
|
|
49
|
+
deps.add(dep);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
dependencies.set(path, deps);
|
|
54
|
+
// 역방향 엣지 추가
|
|
55
|
+
for (const dep of deps) {
|
|
56
|
+
if (!dependents.has(dep)) {
|
|
57
|
+
dependents.set(dep, new Set());
|
|
58
|
+
}
|
|
59
|
+
dependents.get(dep).add(path);
|
|
60
|
+
}
|
|
61
|
+
// result, loading, error 경로도 노드로 등록 (source처럼 취급)
|
|
62
|
+
for (const statePath of [
|
|
63
|
+
definition.resultPath,
|
|
64
|
+
definition.loadingPath,
|
|
65
|
+
definition.errorPath,
|
|
66
|
+
]) {
|
|
67
|
+
if (!nodes.has(statePath)) {
|
|
68
|
+
// Async 결과 경로는 특별한 source로 취급
|
|
69
|
+
dependencies.set(statePath, new Set([path]));
|
|
70
|
+
if (!dependents.has(statePath)) {
|
|
71
|
+
dependents.set(statePath, new Set());
|
|
72
|
+
}
|
|
73
|
+
dependents.get(path).add(statePath);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (!dependents.has(path)) {
|
|
77
|
+
dependents.set(path, new Set());
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// 4. 위상 정렬
|
|
81
|
+
const topologicalOrder = topologicalSort(nodes, dependencies);
|
|
82
|
+
return {
|
|
83
|
+
nodes,
|
|
84
|
+
dependencies,
|
|
85
|
+
dependents,
|
|
86
|
+
topologicalOrder,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 위상 정렬 (Kahn's algorithm)
|
|
91
|
+
*/
|
|
92
|
+
function topologicalSort(nodes, dependencies) {
|
|
93
|
+
const inDegree = new Map();
|
|
94
|
+
const result = [];
|
|
95
|
+
// 진입 차수 계산
|
|
96
|
+
for (const path of nodes.keys()) {
|
|
97
|
+
inDegree.set(path, 0);
|
|
98
|
+
}
|
|
99
|
+
for (const [path, deps] of dependencies) {
|
|
100
|
+
for (const dep of deps) {
|
|
101
|
+
if (nodes.has(dep)) {
|
|
102
|
+
inDegree.set(path, (inDegree.get(path) ?? 0) + 1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// 진입 차수가 0인 노드들로 시작
|
|
107
|
+
const queue = [];
|
|
108
|
+
for (const [path, degree] of inDegree) {
|
|
109
|
+
if (degree === 0) {
|
|
110
|
+
queue.push(path);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
while (queue.length > 0) {
|
|
114
|
+
const current = queue.shift();
|
|
115
|
+
result.push(current);
|
|
116
|
+
// 현재 노드를 의존하는 노드들의 진입 차수 감소
|
|
117
|
+
for (const [path, deps] of dependencies) {
|
|
118
|
+
if (deps.has(current)) {
|
|
119
|
+
const newDegree = (inDegree.get(path) ?? 0) - 1;
|
|
120
|
+
inDegree.set(path, newDegree);
|
|
121
|
+
if (newDegree === 0) {
|
|
122
|
+
queue.push(path);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* 특정 경로의 직접 의존성 조회
|
|
131
|
+
*/
|
|
132
|
+
export function getDirectDependencies(graph, path) {
|
|
133
|
+
return [...(graph.dependencies.get(path) ?? [])];
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* 특정 경로를 직접 의존하는 경로들 조회
|
|
137
|
+
*/
|
|
138
|
+
export function getDirectDependents(graph, path) {
|
|
139
|
+
return [...(graph.dependents.get(path) ?? [])];
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 특정 경로의 모든 의존성 조회 (전이적)
|
|
143
|
+
*/
|
|
144
|
+
export function getAllDependencies(graph, path) {
|
|
145
|
+
const result = new Set();
|
|
146
|
+
const visited = new Set();
|
|
147
|
+
function traverse(current) {
|
|
148
|
+
if (visited.has(current))
|
|
149
|
+
return;
|
|
150
|
+
visited.add(current);
|
|
151
|
+
const deps = graph.dependencies.get(current);
|
|
152
|
+
if (deps) {
|
|
153
|
+
for (const dep of deps) {
|
|
154
|
+
result.add(dep);
|
|
155
|
+
traverse(dep);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
traverse(path);
|
|
160
|
+
return [...result];
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* 특정 경로를 의존하는 모든 경로 조회 (전이적)
|
|
164
|
+
*/
|
|
165
|
+
export function getAllDependents(graph, path) {
|
|
166
|
+
const result = new Set();
|
|
167
|
+
const visited = new Set();
|
|
168
|
+
function traverse(current) {
|
|
169
|
+
if (visited.has(current))
|
|
170
|
+
return;
|
|
171
|
+
visited.add(current);
|
|
172
|
+
const deps = graph.dependents.get(current);
|
|
173
|
+
if (deps) {
|
|
174
|
+
for (const dep of deps) {
|
|
175
|
+
result.add(dep);
|
|
176
|
+
traverse(dep);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
traverse(path);
|
|
181
|
+
return [...result];
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* 순환 의존성이 있는지 확인
|
|
185
|
+
*/
|
|
186
|
+
export function hasCycle(graph) {
|
|
187
|
+
const visited = new Set();
|
|
188
|
+
const recursionStack = new Set();
|
|
189
|
+
function dfs(path) {
|
|
190
|
+
visited.add(path);
|
|
191
|
+
recursionStack.add(path);
|
|
192
|
+
const deps = graph.dependencies.get(path);
|
|
193
|
+
if (deps) {
|
|
194
|
+
for (const dep of deps) {
|
|
195
|
+
if (!visited.has(dep)) {
|
|
196
|
+
if (dfs(dep))
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
else if (recursionStack.has(dep)) {
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
recursionStack.delete(path);
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
for (const path of graph.nodes.keys()) {
|
|
208
|
+
if (!visited.has(path)) {
|
|
209
|
+
if (dfs(path))
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* 두 경로 사이의 경로 찾기 (BFS)
|
|
217
|
+
*/
|
|
218
|
+
export function findPath(graph, from, to) {
|
|
219
|
+
if (from === to)
|
|
220
|
+
return [from];
|
|
221
|
+
const visited = new Set();
|
|
222
|
+
const queue = [
|
|
223
|
+
{ path: from, trail: [from] },
|
|
224
|
+
];
|
|
225
|
+
while (queue.length > 0) {
|
|
226
|
+
const { path, trail } = queue.shift();
|
|
227
|
+
if (visited.has(path))
|
|
228
|
+
continue;
|
|
229
|
+
visited.add(path);
|
|
230
|
+
const deps = graph.dependents.get(path);
|
|
231
|
+
if (deps) {
|
|
232
|
+
for (const dep of deps) {
|
|
233
|
+
if (dep === to) {
|
|
234
|
+
return [...trail, dep];
|
|
235
|
+
}
|
|
236
|
+
if (!visited.has(dep)) {
|
|
237
|
+
queue.push({ path: dep, trail: [...trail, dep] });
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/dag/graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dag/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dag/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { SemanticPath } from '../domain/types.js';
|
|
2
|
+
import type { DependencyGraph, DagNode } from './graph.js';
|
|
3
|
+
import type { Effect } from '../effect/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* 전파 결과
|
|
6
|
+
*/
|
|
7
|
+
export type PropagationResult = {
|
|
8
|
+
/** 변경된 경로와 새 값 */
|
|
9
|
+
changes: Map<SemanticPath, unknown>;
|
|
10
|
+
/** 트리거된 Async Effect들 */
|
|
11
|
+
pendingEffects: Array<{
|
|
12
|
+
path: SemanticPath;
|
|
13
|
+
effect: Effect;
|
|
14
|
+
}>;
|
|
15
|
+
/** 발생한 오류들 */
|
|
16
|
+
errors: Array<{
|
|
17
|
+
path: SemanticPath;
|
|
18
|
+
error: string;
|
|
19
|
+
}>;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* 스냅샷 인터페이스
|
|
23
|
+
*/
|
|
24
|
+
export type SnapshotLike = {
|
|
25
|
+
get: (path: SemanticPath) => unknown;
|
|
26
|
+
set: (path: SemanticPath, value: unknown) => void;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* 변경 전파
|
|
30
|
+
*/
|
|
31
|
+
export declare function propagate(graph: DependencyGraph, changedPaths: SemanticPath[], snapshot: SnapshotLike): PropagationResult;
|
|
32
|
+
/**
|
|
33
|
+
* Async Effect 완료 후 결과 전파
|
|
34
|
+
*/
|
|
35
|
+
export declare function propagateAsyncResult(graph: DependencyGraph, asyncPath: SemanticPath, result: {
|
|
36
|
+
ok: true;
|
|
37
|
+
value: unknown;
|
|
38
|
+
} | {
|
|
39
|
+
ok: false;
|
|
40
|
+
error: string;
|
|
41
|
+
}, snapshot: SnapshotLike): PropagationResult;
|
|
42
|
+
/**
|
|
43
|
+
* 특정 경로 변경 시 영향 분석
|
|
44
|
+
*/
|
|
45
|
+
export declare function analyzeImpact(graph: DependencyGraph, path: SemanticPath): {
|
|
46
|
+
affectedPaths: SemanticPath[];
|
|
47
|
+
affectedNodes: DagNode[];
|
|
48
|
+
asyncTriggers: SemanticPath[];
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* 디바운스된 전파를 위한 유틸리티
|
|
52
|
+
*/
|
|
53
|
+
export declare function createDebouncedPropagator(graph: DependencyGraph, snapshot: SnapshotLike, debounceMs: number): {
|
|
54
|
+
queue: (paths: SemanticPath[]) => void;
|
|
55
|
+
flush: () => PropagationResult;
|
|
56
|
+
cancel: () => void;
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=propagation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"propagation.d.ts","sourceRoot":"","sources":["../../src/dag/propagation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAKjD;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,kBAAkB;IAClB,OAAO,EAAE,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAEpC,yBAAyB;IACzB,cAAc,EAAE,KAAK,CAAC;QACpB,IAAI,EAAE,YAAY,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;IAEH,cAAc;IACd,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,YAAY,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;CACJ,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC;IACrC,GAAG,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACnD,CAAC;AAEF;;GAEG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,eAAe,EACtB,YAAY,EAAE,YAAY,EAAE,EAC5B,QAAQ,EAAE,YAAY,GACrB,iBAAiB,CAkFnB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,eAAe,EACtB,SAAS,EAAE,YAAY,EACvB,MAAM,EAAE;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EACnE,QAAQ,EAAE,YAAY,GACrB,iBAAiB,CAwCnB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,YAAY,GACjB;IACD,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,aAAa,EAAE,OAAO,EAAE,CAAC;IACzB,aAAa,EAAE,YAAY,EAAE,CAAC;CAC/B,CAoBA;AAuCD;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,MAAM,GACjB;IACD,KAAK,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IACvC,KAAK,EAAE,MAAM,iBAAiB,CAAC;IAC/B,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,CA+CA"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { evaluate } from '../expression/evaluator.js';
|
|
2
|
+
import { getAffectedOrder } from './topological.js';
|
|
3
|
+
/**
|
|
4
|
+
* 변경 전파
|
|
5
|
+
*/
|
|
6
|
+
export function propagate(graph, changedPaths, snapshot) {
|
|
7
|
+
const changes = new Map();
|
|
8
|
+
const pendingEffects = [];
|
|
9
|
+
const errors = [];
|
|
10
|
+
// 영향받는 경로들을 위상 정렬 순서로 가져옴
|
|
11
|
+
const affectedOrder = getAffectedOrder(graph, changedPaths);
|
|
12
|
+
// 평가 컨텍스트 생성
|
|
13
|
+
const ctx = {
|
|
14
|
+
get: (path) => {
|
|
15
|
+
// 이미 변경된 값이 있으면 그것을 반환
|
|
16
|
+
if (changes.has(path)) {
|
|
17
|
+
return changes.get(path);
|
|
18
|
+
}
|
|
19
|
+
return snapshot.get(path);
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
// 순서대로 재계산
|
|
23
|
+
for (const path of affectedOrder) {
|
|
24
|
+
const node = graph.nodes.get(path);
|
|
25
|
+
if (!node)
|
|
26
|
+
continue;
|
|
27
|
+
try {
|
|
28
|
+
switch (node.kind) {
|
|
29
|
+
case 'source':
|
|
30
|
+
// Source는 외부 입력이므로 여기서 계산하지 않음
|
|
31
|
+
// 하지만 변경된 경로에 포함되어 있으면 changes에 기록
|
|
32
|
+
if (changedPaths.includes(path)) {
|
|
33
|
+
changes.set(path, snapshot.get(path));
|
|
34
|
+
}
|
|
35
|
+
break;
|
|
36
|
+
case 'derived':
|
|
37
|
+
// Expression 평가
|
|
38
|
+
const derivedResult = evaluate(node.definition.expr, ctx);
|
|
39
|
+
if (derivedResult.ok) {
|
|
40
|
+
const oldValue = snapshot.get(path);
|
|
41
|
+
const newValue = derivedResult.value;
|
|
42
|
+
if (!deepEqual(oldValue, newValue)) {
|
|
43
|
+
changes.set(path, newValue);
|
|
44
|
+
snapshot.set(path, newValue);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
errors.push({ path, error: derivedResult.error });
|
|
49
|
+
}
|
|
50
|
+
break;
|
|
51
|
+
case 'async':
|
|
52
|
+
// 조건 평가
|
|
53
|
+
let shouldTrigger = true;
|
|
54
|
+
if (node.definition.condition) {
|
|
55
|
+
const condResult = evaluate(node.definition.condition, ctx);
|
|
56
|
+
if (condResult.ok) {
|
|
57
|
+
shouldTrigger = Boolean(condResult.value);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
errors.push({ path, error: condResult.error });
|
|
61
|
+
shouldTrigger = false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (shouldTrigger) {
|
|
65
|
+
pendingEffects.push({
|
|
66
|
+
path,
|
|
67
|
+
effect: node.definition.effect,
|
|
68
|
+
});
|
|
69
|
+
// 로딩 상태 업데이트
|
|
70
|
+
changes.set(node.definition.loadingPath, true);
|
|
71
|
+
snapshot.set(node.definition.loadingPath, true);
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
errors.push({
|
|
78
|
+
path,
|
|
79
|
+
error: e instanceof Error ? e.message : String(e),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return { changes, pendingEffects, errors };
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Async Effect 완료 후 결과 전파
|
|
87
|
+
*/
|
|
88
|
+
export function propagateAsyncResult(graph, asyncPath, result, snapshot) {
|
|
89
|
+
const node = graph.nodes.get(asyncPath);
|
|
90
|
+
if (!node || node.kind !== 'async') {
|
|
91
|
+
return { changes: new Map(), pendingEffects: [], errors: [] };
|
|
92
|
+
}
|
|
93
|
+
const changes = new Map();
|
|
94
|
+
const definition = node.definition;
|
|
95
|
+
// 로딩 상태 해제
|
|
96
|
+
changes.set(definition.loadingPath, false);
|
|
97
|
+
snapshot.set(definition.loadingPath, false);
|
|
98
|
+
if (result.ok) {
|
|
99
|
+
// 결과 저장
|
|
100
|
+
changes.set(definition.resultPath, result.value);
|
|
101
|
+
snapshot.set(definition.resultPath, result.value);
|
|
102
|
+
// 에러 클리어
|
|
103
|
+
changes.set(definition.errorPath, null);
|
|
104
|
+
snapshot.set(definition.errorPath, null);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
// 에러 저장
|
|
108
|
+
changes.set(definition.errorPath, result.error);
|
|
109
|
+
snapshot.set(definition.errorPath, result.error);
|
|
110
|
+
}
|
|
111
|
+
// 결과로 인한 추가 전파
|
|
112
|
+
const resultPaths = [definition.resultPath, definition.loadingPath, definition.errorPath];
|
|
113
|
+
const furtherPropagation = propagate(graph, resultPaths, snapshot);
|
|
114
|
+
// 병합
|
|
115
|
+
for (const [path, value] of furtherPropagation.changes) {
|
|
116
|
+
changes.set(path, value);
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
changes,
|
|
120
|
+
pendingEffects: furtherPropagation.pendingEffects,
|
|
121
|
+
errors: furtherPropagation.errors,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 특정 경로 변경 시 영향 분석
|
|
126
|
+
*/
|
|
127
|
+
export function analyzeImpact(graph, path) {
|
|
128
|
+
const affectedOrder = getAffectedOrder(graph, [path]);
|
|
129
|
+
const affectedNodes = [];
|
|
130
|
+
const asyncTriggers = [];
|
|
131
|
+
for (const affectedPath of affectedOrder) {
|
|
132
|
+
const node = graph.nodes.get(affectedPath);
|
|
133
|
+
if (node) {
|
|
134
|
+
affectedNodes.push(node);
|
|
135
|
+
if (node.kind === 'async') {
|
|
136
|
+
asyncTriggers.push(affectedPath);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
affectedPaths: affectedOrder,
|
|
142
|
+
affectedNodes,
|
|
143
|
+
asyncTriggers,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* 깊은 동등성 비교 (간단한 구현)
|
|
148
|
+
*/
|
|
149
|
+
function deepEqual(a, b) {
|
|
150
|
+
if (a === b)
|
|
151
|
+
return true;
|
|
152
|
+
if (a === null || b === null)
|
|
153
|
+
return a === b;
|
|
154
|
+
if (typeof a !== typeof b)
|
|
155
|
+
return false;
|
|
156
|
+
if (typeof a !== 'object')
|
|
157
|
+
return a === b;
|
|
158
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
159
|
+
if (a.length !== b.length)
|
|
160
|
+
return false;
|
|
161
|
+
for (let i = 0; i < a.length; i++) {
|
|
162
|
+
if (!deepEqual(a[i], b[i]))
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
if (Array.isArray(a) || Array.isArray(b))
|
|
168
|
+
return false;
|
|
169
|
+
const aKeys = Object.keys(a);
|
|
170
|
+
const bKeys = Object.keys(b);
|
|
171
|
+
if (aKeys.length !== bKeys.length)
|
|
172
|
+
return false;
|
|
173
|
+
for (const key of aKeys) {
|
|
174
|
+
if (!deepEqual(a[key], b[key])) {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* 디바운스된 전파를 위한 유틸리티
|
|
182
|
+
*/
|
|
183
|
+
export function createDebouncedPropagator(graph, snapshot, debounceMs) {
|
|
184
|
+
let pendingPaths = new Set();
|
|
185
|
+
let timeoutId = null;
|
|
186
|
+
let lastResult = {
|
|
187
|
+
changes: new Map(),
|
|
188
|
+
pendingEffects: [],
|
|
189
|
+
errors: [],
|
|
190
|
+
};
|
|
191
|
+
return {
|
|
192
|
+
queue(paths) {
|
|
193
|
+
for (const path of paths) {
|
|
194
|
+
pendingPaths.add(path);
|
|
195
|
+
}
|
|
196
|
+
if (timeoutId) {
|
|
197
|
+
clearTimeout(timeoutId);
|
|
198
|
+
}
|
|
199
|
+
timeoutId = setTimeout(() => {
|
|
200
|
+
this.flush();
|
|
201
|
+
}, debounceMs);
|
|
202
|
+
},
|
|
203
|
+
flush() {
|
|
204
|
+
if (timeoutId) {
|
|
205
|
+
clearTimeout(timeoutId);
|
|
206
|
+
timeoutId = null;
|
|
207
|
+
}
|
|
208
|
+
if (pendingPaths.size === 0) {
|
|
209
|
+
return lastResult;
|
|
210
|
+
}
|
|
211
|
+
lastResult = propagate(graph, [...pendingPaths], snapshot);
|
|
212
|
+
pendingPaths = new Set();
|
|
213
|
+
return lastResult;
|
|
214
|
+
},
|
|
215
|
+
cancel() {
|
|
216
|
+
if (timeoutId) {
|
|
217
|
+
clearTimeout(timeoutId);
|
|
218
|
+
timeoutId = null;
|
|
219
|
+
}
|
|
220
|
+
pendingPaths = new Set();
|
|
221
|
+
},
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=propagation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"propagation.js","sourceRoot":"","sources":["../../src/dag/propagation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { SemanticPath } from '../domain/types.js';
|
|
2
|
+
import type { DependencyGraph } from './graph.js';
|
|
3
|
+
/**
|
|
4
|
+
* 위상 정렬 결과
|
|
5
|
+
*/
|
|
6
|
+
export type TopologicalSortResult = {
|
|
7
|
+
ok: true;
|
|
8
|
+
order: SemanticPath[];
|
|
9
|
+
} | {
|
|
10
|
+
ok: false;
|
|
11
|
+
cycle: SemanticPath[];
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* 고급 위상 정렬 (순환 탐지 포함)
|
|
15
|
+
*/
|
|
16
|
+
export declare function topologicalSortWithCycleDetection(graph: DependencyGraph): TopologicalSortResult;
|
|
17
|
+
/**
|
|
18
|
+
* 레벨별 정렬 (같은 레벨의 노드들은 병렬 처리 가능)
|
|
19
|
+
*/
|
|
20
|
+
export declare function getLevelOrder(graph: DependencyGraph): SemanticPath[][];
|
|
21
|
+
/**
|
|
22
|
+
* 역방향 위상 정렬 (리프부터 루트로)
|
|
23
|
+
*/
|
|
24
|
+
export declare function reverseTopologicalSort(graph: DependencyGraph): SemanticPath[];
|
|
25
|
+
/**
|
|
26
|
+
* 부분 그래프의 위상 정렬
|
|
27
|
+
*/
|
|
28
|
+
export declare function partialTopologicalSort(graph: DependencyGraph, paths: SemanticPath[]): SemanticPath[];
|
|
29
|
+
/**
|
|
30
|
+
* 변경된 경로들의 영향을 받는 경로들의 위상 정렬된 순서
|
|
31
|
+
*/
|
|
32
|
+
export declare function getAffectedOrder(graph: DependencyGraph, changedPaths: SemanticPath[]): SemanticPath[];
|
|
33
|
+
//# sourceMappingURL=topological.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topological.d.ts","sourceRoot":"","sources":["../../src/dag/topological.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,YAAY,EAAE,CAAA;CAAE,GACnC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC;AAEzC;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,eAAe,GACrB,qBAAqB,CAoDvB;AA0DD;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,EAAE,EAAE,CAyCtE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,EAAE,CAE7E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,YAAY,EAAE,GACpB,YAAY,EAAE,CAGhB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,eAAe,EACtB,YAAY,EAAE,YAAY,EAAE,GAC3B,YAAY,EAAE,CAsBhB"}
|