@allternit/ix 0.1.0 → 0.1.1
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/README.md +6 -6
- package/dist/adapters/json-render.d.ts +5 -5
- package/dist/adapters/json-render.js +12 -12
- package/dist/collab/visual-editor.d.ts +1 -1
- package/dist/collab/visual-editor.js +4 -4
- package/dist/collab/visual-editor.js.map +1 -1
- package/dist/collab/yjs-adapter.d.ts +1 -1
- package/dist/collab/yjs-adapter.js +2 -2
- package/dist/collab/yjs-adapter.js.map +1 -1
- package/dist/collab/yjs-client.js +1 -1
- package/dist/collab/yjs-client.js.map +1 -1
- package/dist/collab/yjs-types.js +1 -1
- package/dist/collab/yjs-types.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/pipeline/llm-to-ix.d.ts +5 -5
- package/dist/pipeline/llm-to-ix.d.ts.map +1 -1
- package/dist/pipeline/llm-to-ix.js +6 -6
- package/dist/react/renderer.d.ts +2 -2
- package/dist/react/renderer.js +3 -3
- package/dist/react/renderer.js.map +1 -1
- package/dist/renderer/renderer.d.ts +1 -1
- package/dist/renderer/renderer.js +1 -1
- package/dist/runtime/capsule-runtime.d.ts +1 -1
- package/dist/runtime/capsule-runtime.js +1 -1
- package/dist/sdk/api.d.ts +3 -3
- package/dist/sdk/api.js +3 -3
- package/dist/sdk/index.d.ts +2 -2
- package/dist/sdk/index.js +2 -2
- package/dist/sdk/react.d.ts +2 -2
- package/dist/sdk/react.js +2 -2
- package/dist/state/index.d.ts +1 -1
- package/dist/state/index.js +1 -1
- package/dist/state/store.d.ts +1 -1
- package/dist/state/store.js +3 -3
- package/dist/state/store.js.map +1 -1
- package/dist/svelte/index.d.ts +1 -1
- package/dist/svelte/index.js +1 -1
- package/dist/svelte/renderer.d.ts +3 -3
- package/dist/svelte/renderer.js +4 -4
- package/dist/svelte/renderer.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -1
- package/dist/vue/renderer.d.ts +3 -3
- package/dist/vue/renderer.js +5 -5
- package/dist/vue/renderer.js.map +1 -1
- package/package.json +8 -8
- package/dist/adapters/json-render.d.ts.bak +0 -211
- package/dist/adapters/json-render.js.bak +0 -576
- package/dist/catalog/registry.d.ts.bak +0 -65
- package/dist/catalog/registry.js.bak +0 -388
- package/dist/collab/capsule-registry.d.ts.bak +0 -114
- package/dist/collab/capsule-registry.js.bak +0 -271
- package/dist/collab/index.d.ts.bak +0 -21
- package/dist/collab/index.js.bak +0 -32
- package/dist/collab/visual-editor.d.ts.bak +0 -199
- package/dist/collab/visual-editor.js.bak +0 -259
- package/dist/collab/yjs-adapter.d.ts.bak +0 -95
- package/dist/collab/yjs-adapter.js.bak +0 -282
- package/dist/collab/yjs-client.d.ts.bak +0 -101
- package/dist/collab/yjs-client.js.bak +0 -193
- package/dist/collab/yjs-protocols.d.ts.bak +0 -128
- package/dist/collab/yjs-protocols.js.bak +0 -245
- package/dist/collab/yjs-types.d.ts.bak +0 -201
- package/dist/collab/yjs-types.js.bak +0 -45
- package/dist/index.d.ts.bak +0 -38
- package/dist/index.js.bak +0 -48
- package/dist/pipeline/llm-to-ix.d.ts.bak +0 -249
- package/dist/pipeline/llm-to-ix.js.bak +0 -992
- package/dist/react/index.d.ts.bak +0 -18
- package/dist/react/index.js.bak +0 -18
- package/dist/react/renderer.d.ts.bak +0 -47
- package/dist/react/renderer.js.bak +0 -420
- package/dist/renderer/renderer.d.ts.bak +0 -55
- package/dist/renderer/renderer.js.bak +0 -232
- package/dist/runtime/capsule-runtime.d.ts.bak +0 -227
- package/dist/runtime/capsule-runtime.js.bak +0 -563
- package/dist/runtime/policy-gates.d.ts.bak +0 -116
- package/dist/runtime/policy-gates.js.bak +0 -317
- package/dist/schema/ui-ir.d.ts.bak +0 -26
- package/dist/schema/ui-ir.js.bak +0 -51
- package/dist/sdk/api.d.ts.bak +0 -101
- package/dist/sdk/api.js.bak +0 -177
- package/dist/sdk/index.d.ts.bak +0 -9
- package/dist/sdk/index.js.bak +0 -10
- package/dist/sdk/react.d.ts.bak +0 -63
- package/dist/sdk/react.js.bak +0 -161
- package/dist/state/index.d.ts.bak +0 -8
- package/dist/state/index.js.bak +0 -8
- package/dist/state/patch.d.ts.bak +0 -73
- package/dist/state/patch.js.bak +0 -437
- package/dist/state/store.d.ts.bak +0 -50
- package/dist/state/store.js.bak +0 -246
- package/dist/svelte/index.d.ts.bak +0 -15
- package/dist/svelte/index.js.bak +0 -15
- package/dist/svelte/renderer.d.ts.bak +0 -35
- package/dist/svelte/renderer.js.bak +0 -317
- package/dist/types/index.d.ts.bak +0 -349
- package/dist/types/index.js.bak +0 -152
- package/dist/vue/index.d.ts.bak +0 -18
- package/dist/vue/index.js.bak +0 -18
- package/dist/vue/renderer.d.ts.bak +0 -46
- package/dist/vue/renderer.js.bak +0 -302
package/dist/state/patch.js.bak
DELETED
|
@@ -1,437 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSON Patch Engine (RFC 6902)
|
|
3
|
-
*
|
|
4
|
-
* Implements JSON Patch operations for state synchronization.
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* JSON Pointer helpers
|
|
8
|
-
*/
|
|
9
|
-
export function decodeJsonPointer(pointer) {
|
|
10
|
-
if (pointer === '' || pointer === '/')
|
|
11
|
-
return [];
|
|
12
|
-
if (!pointer.startsWith('/')) {
|
|
13
|
-
throw new Error(`Invalid JSON Pointer: ${pointer}`);
|
|
14
|
-
}
|
|
15
|
-
return pointer
|
|
16
|
-
.slice(1)
|
|
17
|
-
.split('/')
|
|
18
|
-
.map((segment) => segment.replace(/~1/g, '/').replace(/~0/g, '~'));
|
|
19
|
-
}
|
|
20
|
-
export function encodeJsonPointer(segments) {
|
|
21
|
-
if (segments.length === 0)
|
|
22
|
-
return '';
|
|
23
|
-
return '/' + segments
|
|
24
|
-
.map((segment) => segment.replace(/~/g, '~0').replace(/\//g, '~1'))
|
|
25
|
-
.join('/');
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Get value at JSON Pointer path
|
|
29
|
-
*/
|
|
30
|
-
export function getValueAtPath(obj, pointer) {
|
|
31
|
-
const segments = decodeJsonPointer(pointer);
|
|
32
|
-
let current = obj;
|
|
33
|
-
for (const segment of segments) {
|
|
34
|
-
if (current === null || typeof current !== 'object') {
|
|
35
|
-
return undefined;
|
|
36
|
-
}
|
|
37
|
-
if (Array.isArray(current)) {
|
|
38
|
-
const index = segment === '-' ? current.length : parseInt(segment, 10);
|
|
39
|
-
if (isNaN(index) || index < 0 || index > current.length) {
|
|
40
|
-
return undefined;
|
|
41
|
-
}
|
|
42
|
-
current = current[index];
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
current = current[segment];
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return current;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Set value at JSON Pointer path
|
|
52
|
-
*/
|
|
53
|
-
export function setValueAtPath(obj, pointer, value, operation) {
|
|
54
|
-
const segments = decodeJsonPointer(pointer);
|
|
55
|
-
if (segments.length === 0) {
|
|
56
|
-
return operation === 'remove' ? undefined : value;
|
|
57
|
-
}
|
|
58
|
-
// Clone to avoid mutation
|
|
59
|
-
const root = deepClone(obj);
|
|
60
|
-
let current = root;
|
|
61
|
-
for (let i = 0; i < segments.length - 1; i++) {
|
|
62
|
-
const segment = segments[i];
|
|
63
|
-
const nextSegment = segments[i + 1];
|
|
64
|
-
if (Array.isArray(current)) {
|
|
65
|
-
const index = parseInt(segment, 10);
|
|
66
|
-
if (isNaN(index) || index < 0 || index >= current.length) {
|
|
67
|
-
throw new Error(`Array index out of bounds: ${segment}`);
|
|
68
|
-
}
|
|
69
|
-
// Ensure next level exists
|
|
70
|
-
if (current[index] === null || typeof current[index] !== 'object') {
|
|
71
|
-
const isNextArray = !isNaN(parseInt(nextSegment, 10)) || nextSegment === '-';
|
|
72
|
-
current[index] = isNextArray ? [] : {};
|
|
73
|
-
}
|
|
74
|
-
current = current[index];
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
const currentObj = current;
|
|
78
|
-
if (!(segment in currentObj) || currentObj[segment] === null || typeof currentObj[segment] !== 'object') {
|
|
79
|
-
const isNextArray = !isNaN(parseInt(nextSegment, 10)) || nextSegment === '-';
|
|
80
|
-
currentObj[segment] = isNextArray ? [] : {};
|
|
81
|
-
}
|
|
82
|
-
current = currentObj[segment];
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
const lastSegment = segments[segments.length - 1];
|
|
86
|
-
if (Array.isArray(current)) {
|
|
87
|
-
const index = lastSegment === '-' ? current.length : parseInt(lastSegment, 10);
|
|
88
|
-
if (operation === 'remove') {
|
|
89
|
-
if (index < 0 || index >= current.length) {
|
|
90
|
-
throw new Error(`Array index out of bounds: ${lastSegment}`);
|
|
91
|
-
}
|
|
92
|
-
current.splice(index, 1);
|
|
93
|
-
}
|
|
94
|
-
else if (operation === 'add' && lastSegment === '-') {
|
|
95
|
-
current.push(value);
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
if (isNaN(index) || index < 0 || (operation === 'replace' && index >= current.length)) {
|
|
99
|
-
throw new Error(`Invalid array index: ${lastSegment}`);
|
|
100
|
-
}
|
|
101
|
-
current[index] = value;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
const currentObj = current;
|
|
106
|
-
if (operation === 'remove') {
|
|
107
|
-
delete currentObj[lastSegment];
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
currentObj[lastSegment] = value;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return root;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Deep clone value
|
|
117
|
-
*/
|
|
118
|
-
function deepClone(value) {
|
|
119
|
-
if (value === null || typeof value !== 'object') {
|
|
120
|
-
return value;
|
|
121
|
-
}
|
|
122
|
-
if (Array.isArray(value)) {
|
|
123
|
-
return value.map(deepClone);
|
|
124
|
-
}
|
|
125
|
-
if (typeof value === 'object') {
|
|
126
|
-
const cloned = {};
|
|
127
|
-
for (const key of Object.keys(value)) {
|
|
128
|
-
cloned[key] = deepClone(value[key]);
|
|
129
|
-
}
|
|
130
|
-
return cloned;
|
|
131
|
-
}
|
|
132
|
-
return value;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Deep equality check
|
|
136
|
-
*/
|
|
137
|
-
function deepEqual(a, b) {
|
|
138
|
-
if (a === b)
|
|
139
|
-
return true;
|
|
140
|
-
if (a === null || b === null)
|
|
141
|
-
return false;
|
|
142
|
-
if (typeof a !== typeof b)
|
|
143
|
-
return false;
|
|
144
|
-
if (typeof a !== 'object')
|
|
145
|
-
return false;
|
|
146
|
-
if (Array.isArray(a) !== Array.isArray(b))
|
|
147
|
-
return false;
|
|
148
|
-
if (Array.isArray(a)) {
|
|
149
|
-
if (a.length !== b.length)
|
|
150
|
-
return false;
|
|
151
|
-
for (let i = 0; i < a.length; i++) {
|
|
152
|
-
if (!deepEqual(a[i], b[i]))
|
|
153
|
-
return false;
|
|
154
|
-
}
|
|
155
|
-
return true;
|
|
156
|
-
}
|
|
157
|
-
const keysA = Object.keys(a);
|
|
158
|
-
const keysB = Object.keys(b);
|
|
159
|
-
if (keysA.length !== keysB.length)
|
|
160
|
-
return false;
|
|
161
|
-
for (const key of keysA) {
|
|
162
|
-
if (!keysB.includes(key))
|
|
163
|
-
return false;
|
|
164
|
-
if (!deepEqual(a[key], b[key])) {
|
|
165
|
-
return false;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
return true;
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Apply single patch operation
|
|
172
|
-
*/
|
|
173
|
-
export function applyOperation(state, operation) {
|
|
174
|
-
try {
|
|
175
|
-
switch (operation.op) {
|
|
176
|
-
case 'add': {
|
|
177
|
-
if (operation.value === undefined) {
|
|
178
|
-
return { success: false, newState: state, error: 'Add operation requires value' };
|
|
179
|
-
}
|
|
180
|
-
const newState = setValueAtPath(state, operation.path, operation.value, 'add');
|
|
181
|
-
return { success: true, newState: newState };
|
|
182
|
-
}
|
|
183
|
-
case 'remove': {
|
|
184
|
-
if (!getValueAtPath(state, operation.path)) {
|
|
185
|
-
return { success: false, newState: state, error: `Path not found: ${operation.path}` };
|
|
186
|
-
}
|
|
187
|
-
const newState = setValueAtPath(state, operation.path, undefined, 'remove');
|
|
188
|
-
return { success: true, newState: newState };
|
|
189
|
-
}
|
|
190
|
-
case 'replace': {
|
|
191
|
-
if (operation.value === undefined) {
|
|
192
|
-
return { success: false, newState: state, error: 'Replace operation requires value' };
|
|
193
|
-
}
|
|
194
|
-
if (getValueAtPath(state, operation.path) === undefined) {
|
|
195
|
-
return { success: false, newState: state, error: `Path not found: ${operation.path}` };
|
|
196
|
-
}
|
|
197
|
-
const newState = setValueAtPath(state, operation.path, operation.value, 'replace');
|
|
198
|
-
return { success: true, newState: newState };
|
|
199
|
-
}
|
|
200
|
-
case 'move': {
|
|
201
|
-
if (!operation.from) {
|
|
202
|
-
return { success: false, newState: state, error: 'Move operation requires from path' };
|
|
203
|
-
}
|
|
204
|
-
const value = getValueAtPath(state, operation.from);
|
|
205
|
-
if (value === undefined) {
|
|
206
|
-
return { success: false, newState: state, error: `Source path not found: ${operation.from}` };
|
|
207
|
-
}
|
|
208
|
-
let newState = setValueAtPath(state, operation.from, undefined, 'remove');
|
|
209
|
-
newState = setValueAtPath(newState, operation.path, value, 'add');
|
|
210
|
-
return { success: true, newState: newState };
|
|
211
|
-
}
|
|
212
|
-
case 'copy': {
|
|
213
|
-
if (!operation.from) {
|
|
214
|
-
return { success: false, newState: state, error: 'Copy operation requires from path' };
|
|
215
|
-
}
|
|
216
|
-
const value = getValueAtPath(state, operation.from);
|
|
217
|
-
if (value === undefined) {
|
|
218
|
-
return { success: false, newState: state, error: `Source path not found: ${operation.from}` };
|
|
219
|
-
}
|
|
220
|
-
const newState = setValueAtPath(state, operation.path, deepClone(value), 'add');
|
|
221
|
-
return { success: true, newState: newState };
|
|
222
|
-
}
|
|
223
|
-
case 'test': {
|
|
224
|
-
if (operation.value === undefined) {
|
|
225
|
-
return { success: false, newState: state, error: 'Test operation requires value' };
|
|
226
|
-
}
|
|
227
|
-
const currentValue = getValueAtPath(state, operation.path);
|
|
228
|
-
if (!deepEqual(currentValue, operation.value)) {
|
|
229
|
-
return {
|
|
230
|
-
success: false,
|
|
231
|
-
newState: state,
|
|
232
|
-
error: `Test failed: expected ${JSON.stringify(operation.value)}, got ${JSON.stringify(currentValue)}`
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
return { success: true, newState: state };
|
|
236
|
-
}
|
|
237
|
-
default:
|
|
238
|
-
return { success: false, newState: state, error: `Unknown operation: ${operation.op}` };
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
catch (error) {
|
|
242
|
-
return {
|
|
243
|
-
success: false,
|
|
244
|
-
newState: state,
|
|
245
|
-
error: error instanceof Error ? error.message : String(error)
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Apply JSON Patch to state
|
|
251
|
-
*/
|
|
252
|
-
export function applyPatch(state, patch) {
|
|
253
|
-
let currentState = deepClone(state);
|
|
254
|
-
for (let i = 0; i < patch.length; i++) {
|
|
255
|
-
const operation = patch[i];
|
|
256
|
-
const result = applyOperation(currentState, operation);
|
|
257
|
-
if (!result.success) {
|
|
258
|
-
return {
|
|
259
|
-
success: false,
|
|
260
|
-
operations: patch.slice(0, i + 1),
|
|
261
|
-
failedAt: i,
|
|
262
|
-
error: result.error,
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
currentState = result.newState;
|
|
266
|
-
}
|
|
267
|
-
return {
|
|
268
|
-
success: true,
|
|
269
|
-
operations: patch,
|
|
270
|
-
newState: currentState,
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* Apply patch to state store
|
|
275
|
-
*/
|
|
276
|
-
export function applyPatchToStore(store, patch) {
|
|
277
|
-
const snapshot = store.snapshot();
|
|
278
|
-
const result = applyPatch(snapshot, patch);
|
|
279
|
-
if (result.success) {
|
|
280
|
-
store.restore(result.operations.reduce((state, op) => {
|
|
281
|
-
if (op.op !== 'test') {
|
|
282
|
-
const { newState } = applyOperation(state, op);
|
|
283
|
-
return newState;
|
|
284
|
-
}
|
|
285
|
-
return state;
|
|
286
|
-
}, snapshot));
|
|
287
|
-
}
|
|
288
|
-
return result;
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
* Generate JSON Patch from two objects (diff)
|
|
292
|
-
*/
|
|
293
|
-
export function generatePatch(from, to, path = '') {
|
|
294
|
-
const patch = [];
|
|
295
|
-
// Handle primitive types
|
|
296
|
-
if (typeof from !== typeof to || (typeof from !== 'object' && from !== to)) {
|
|
297
|
-
if (from === undefined) {
|
|
298
|
-
patch.push({ op: 'add', path, value: to });
|
|
299
|
-
}
|
|
300
|
-
else if (to === undefined) {
|
|
301
|
-
patch.push({ op: 'remove', path });
|
|
302
|
-
}
|
|
303
|
-
else {
|
|
304
|
-
patch.push({ op: 'replace', path, value: to });
|
|
305
|
-
}
|
|
306
|
-
return patch;
|
|
307
|
-
}
|
|
308
|
-
// Handle null
|
|
309
|
-
if (from === null || to === null) {
|
|
310
|
-
if (from !== to) {
|
|
311
|
-
patch.push({ op: 'replace', path, value: to });
|
|
312
|
-
}
|
|
313
|
-
return patch;
|
|
314
|
-
}
|
|
315
|
-
// Handle arrays
|
|
316
|
-
if (Array.isArray(from) && Array.isArray(to)) {
|
|
317
|
-
// Simple array diff - could be optimized with LCS
|
|
318
|
-
const maxLen = Math.max(from.length, to.length);
|
|
319
|
-
for (let i = 0; i < maxLen; i++) {
|
|
320
|
-
const itemPath = path + '/' + i;
|
|
321
|
-
if (i >= from.length) {
|
|
322
|
-
patch.push({ op: 'add', path: itemPath, value: to[i] });
|
|
323
|
-
}
|
|
324
|
-
else if (i >= to.length) {
|
|
325
|
-
patch.push({ op: 'remove', path: itemPath });
|
|
326
|
-
}
|
|
327
|
-
else {
|
|
328
|
-
patch.push(...generatePatch(from[i], to[i], itemPath));
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
return patch;
|
|
332
|
-
}
|
|
333
|
-
// Handle objects
|
|
334
|
-
if (typeof from === 'object' && typeof to === 'object') {
|
|
335
|
-
const fromKeys = new Set(Object.keys(from));
|
|
336
|
-
const toKeys = new Set(Object.keys(to));
|
|
337
|
-
const allKeys = new Set([...fromKeys, ...toKeys]);
|
|
338
|
-
for (const key of allKeys) {
|
|
339
|
-
const keyPath = path ? `${path}/${key}` : `/${key}`;
|
|
340
|
-
if (!fromKeys.has(key)) {
|
|
341
|
-
// Added key
|
|
342
|
-
patch.push({ op: 'add', path: keyPath, value: to[key] });
|
|
343
|
-
}
|
|
344
|
-
else if (!toKeys.has(key)) {
|
|
345
|
-
// Removed key
|
|
346
|
-
patch.push({ op: 'remove', path: keyPath });
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
// Modified key
|
|
350
|
-
patch.push(...generatePatch(from[key], to[key], keyPath));
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
return patch;
|
|
354
|
-
}
|
|
355
|
-
return patch;
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* Invert a patch for undo functionality
|
|
359
|
-
*/
|
|
360
|
-
export function invertPatch(patch, state) {
|
|
361
|
-
const inverted = [];
|
|
362
|
-
// Process in reverse order
|
|
363
|
-
for (let i = patch.length - 1; i >= 0; i--) {
|
|
364
|
-
const op = patch[i];
|
|
365
|
-
switch (op.op) {
|
|
366
|
-
case 'add': {
|
|
367
|
-
// Undo add -> remove
|
|
368
|
-
inverted.push({ op: 'remove', path: op.path });
|
|
369
|
-
break;
|
|
370
|
-
}
|
|
371
|
-
case 'remove': {
|
|
372
|
-
// Undo remove -> add with original value
|
|
373
|
-
const originalValue = getValueAtPath(state, op.path);
|
|
374
|
-
inverted.push({ op: 'add', path: op.path, value: originalValue });
|
|
375
|
-
break;
|
|
376
|
-
}
|
|
377
|
-
case 'replace': {
|
|
378
|
-
// Undo replace -> replace with original value
|
|
379
|
-
const originalValue = getValueAtPath(state, op.path);
|
|
380
|
-
inverted.push({ op: 'replace', path: op.path, value: originalValue });
|
|
381
|
-
break;
|
|
382
|
-
}
|
|
383
|
-
case 'move': {
|
|
384
|
-
// Undo move -> move back
|
|
385
|
-
if (op.from) {
|
|
386
|
-
inverted.push({ op: 'move', path: op.from, from: op.path });
|
|
387
|
-
}
|
|
388
|
-
break;
|
|
389
|
-
}
|
|
390
|
-
case 'copy': {
|
|
391
|
-
// Undo copy -> remove
|
|
392
|
-
inverted.push({ op: 'remove', path: op.path });
|
|
393
|
-
break;
|
|
394
|
-
}
|
|
395
|
-
// test operations are self-inverting
|
|
396
|
-
case 'test': {
|
|
397
|
-
inverted.push(op);
|
|
398
|
-
break;
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
return inverted;
|
|
403
|
-
}
|
|
404
|
-
/**
|
|
405
|
-
* Validate patch operation
|
|
406
|
-
*/
|
|
407
|
-
export function validateOperation(op) {
|
|
408
|
-
if (!op.op || !['add', 'remove', 'replace', 'move', 'copy', 'test'].includes(op.op)) {
|
|
409
|
-
return { valid: false, error: `Invalid operation: ${op.op}` };
|
|
410
|
-
}
|
|
411
|
-
if (!op.path || !op.path.startsWith('/')) {
|
|
412
|
-
return { valid: false, error: `Invalid path: ${op.path}` };
|
|
413
|
-
}
|
|
414
|
-
if ((op.op === 'add' || op.op === 'replace' || op.op === 'test') && op.value === undefined) {
|
|
415
|
-
return { valid: false, error: `${op.op} operation requires value` };
|
|
416
|
-
}
|
|
417
|
-
if ((op.op === 'move' || op.op === 'copy') && !op.from) {
|
|
418
|
-
return { valid: false, error: `${op.op} operation requires from path` };
|
|
419
|
-
}
|
|
420
|
-
if ((op.op === 'move' || op.op === 'copy') && op.from && !op.from.startsWith('/')) {
|
|
421
|
-
return { valid: false, error: `Invalid from path: ${op.from}` };
|
|
422
|
-
}
|
|
423
|
-
return { valid: true };
|
|
424
|
-
}
|
|
425
|
-
/**
|
|
426
|
-
* Validate entire patch
|
|
427
|
-
*/
|
|
428
|
-
export function validatePatch(patch) {
|
|
429
|
-
for (let i = 0; i < patch.length; i++) {
|
|
430
|
-
const result = validateOperation(patch[i]);
|
|
431
|
-
if (!result.valid) {
|
|
432
|
-
return { valid: false, error: result.error, index: i };
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
return { valid: true };
|
|
436
|
-
}
|
|
437
|
-
//# sourceMappingURL=patch.js.map
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* State Store
|
|
3
|
-
*
|
|
4
|
-
* Scoped state management for A2R-IX with binding support.
|
|
5
|
-
*/
|
|
6
|
-
import type { StateVariable, ComputedValue } from '../types';
|
|
7
|
-
export interface StateStore {
|
|
8
|
-
/** Get value at path */
|
|
9
|
-
get<T>(path: string): T | undefined;
|
|
10
|
-
/** Set value at path */
|
|
11
|
-
set<T>(path: string, value: T): void;
|
|
12
|
-
/** Subscribe to changes */
|
|
13
|
-
subscribe(path: string, callback: (value: unknown) => void): () => void;
|
|
14
|
-
/** Compute derived value */
|
|
15
|
-
compute<T>(name: string, deps: string[], compute: () => T): void;
|
|
16
|
-
/** Bind component prop to state */
|
|
17
|
-
bind(componentId: string, prop: string, statePath: string): void;
|
|
18
|
-
/** Get all bindings for a component */
|
|
19
|
-
getBindings(componentId: string): Array<{
|
|
20
|
-
prop: string;
|
|
21
|
-
statePath: string;
|
|
22
|
-
}>;
|
|
23
|
-
/** Batch multiple updates */
|
|
24
|
-
batch(updates: Record<string, unknown>): void;
|
|
25
|
-
/** Get state snapshot */
|
|
26
|
-
snapshot(): Record<string, unknown>;
|
|
27
|
-
/** Restore from snapshot */
|
|
28
|
-
restore(snapshot: Record<string, unknown>): void;
|
|
29
|
-
/** Reset to initial values */
|
|
30
|
-
reset(): void;
|
|
31
|
-
}
|
|
32
|
-
export interface StateStoreConfig {
|
|
33
|
-
/** Initial state values */
|
|
34
|
-
initial?: Record<string, unknown>;
|
|
35
|
-
/** State variable definitions */
|
|
36
|
-
variables?: StateVariable[];
|
|
37
|
-
/** Computed values */
|
|
38
|
-
computed?: ComputedValue[];
|
|
39
|
-
/** Scope ID (for persistence) */
|
|
40
|
-
scopeId?: string;
|
|
41
|
-
/** Persist to storage */
|
|
42
|
-
persist?: boolean;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Create state store
|
|
46
|
-
*/
|
|
47
|
-
export declare function createStateStore(config?: StateStoreConfig): StateStore;
|
|
48
|
-
export declare function getStateStore(scopeId: string, config?: StateStoreConfig): StateStore;
|
|
49
|
-
export declare function clearStateStore(scopeId: string): void;
|
|
50
|
-
//# sourceMappingURL=store.d.ts.map
|