@skygraph/core 0.0.0-placeholder.0 → 0.5.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.
Files changed (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +42 -6
  3. package/dist/calendar.cjs +404 -0
  4. package/dist/calendar.cjs.map +1 -0
  5. package/dist/calendar.d.cts +209 -0
  6. package/dist/calendar.d.ts +209 -0
  7. package/dist/calendar.js +12 -0
  8. package/dist/calendar.js.map +1 -0
  9. package/dist/chunk-5CCD5Q4B.js +36 -0
  10. package/dist/chunk-5CCD5Q4B.js.map +1 -0
  11. package/dist/chunk-7FA2TBSZ.js +1211 -0
  12. package/dist/chunk-7FA2TBSZ.js.map +1 -0
  13. package/dist/chunk-AB3RLBLW.js +357 -0
  14. package/dist/chunk-AB3RLBLW.js.map +1 -0
  15. package/dist/chunk-GEMALROQ.js +258 -0
  16. package/dist/chunk-GEMALROQ.js.map +1 -0
  17. package/dist/chunk-IY6LJU3L.js +256 -0
  18. package/dist/chunk-IY6LJU3L.js.map +1 -0
  19. package/dist/chunk-KMGRNPLG.js +453 -0
  20. package/dist/chunk-KMGRNPLG.js.map +1 -0
  21. package/dist/chunk-Y7FTBBYX.js +397 -0
  22. package/dist/chunk-Y7FTBBYX.js.map +1 -0
  23. package/dist/chunk-ZWB7JGAJ.js +488 -0
  24. package/dist/chunk-ZWB7JGAJ.js.map +1 -0
  25. package/dist/form.cjs +498 -0
  26. package/dist/form.cjs.map +1 -0
  27. package/dist/form.d.cts +130 -0
  28. package/dist/form.d.ts +130 -0
  29. package/dist/form.js +8 -0
  30. package/dist/form.js.map +1 -0
  31. package/dist/graph.cjs +1269 -0
  32. package/dist/graph.cjs.map +1 -0
  33. package/dist/graph.d.cts +671 -0
  34. package/dist/graph.d.ts +671 -0
  35. package/dist/graph.js +34 -0
  36. package/dist/graph.js.map +1 -0
  37. package/dist/index.cjs +3860 -0
  38. package/dist/index.cjs.map +1 -0
  39. package/dist/index.d.cts +144 -0
  40. package/dist/index.d.ts +144 -0
  41. package/dist/index.js +477 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/runtime-internal.cjs +339 -0
  44. package/dist/runtime-internal.cjs.map +1 -0
  45. package/dist/runtime-internal.d.cts +130 -0
  46. package/dist/runtime-internal.d.ts +130 -0
  47. package/dist/runtime-internal.js +67 -0
  48. package/dist/runtime-internal.js.map +1 -0
  49. package/dist/table.cjs +537 -0
  50. package/dist/table.cjs.map +1 -0
  51. package/dist/table.d.cts +215 -0
  52. package/dist/table.d.ts +215 -0
  53. package/dist/table.js +16 -0
  54. package/dist/table.js.map +1 -0
  55. package/dist/tree.cjs +442 -0
  56. package/dist/tree.cjs.map +1 -0
  57. package/dist/tree.d.cts +76 -0
  58. package/dist/tree.d.ts +76 -0
  59. package/dist/tree.js +8 -0
  60. package/dist/tree.js.map +1 -0
  61. package/dist/types-B-rKQJ4R.d.cts +35 -0
  62. package/dist/types-B-rKQJ4R.d.ts +35 -0
  63. package/dist/virtual.cjs +283 -0
  64. package/dist/virtual.cjs.map +1 -0
  65. package/dist/virtual.d.cts +96 -0
  66. package/dist/virtual.d.ts +96 -0
  67. package/dist/virtual.js +9 -0
  68. package/dist/virtual.js.map +1 -0
  69. package/package.json +98 -18
  70. package/index.js +0 -3
package/dist/index.js ADDED
@@ -0,0 +1,477 @@
1
+ import {
2
+ createForm
3
+ } from "./chunk-KMGRNPLG.js";
4
+ import {
5
+ computeAggregate,
6
+ createTable,
7
+ matchesColumnFilter,
8
+ matchesOperator,
9
+ resolveOperator
10
+ } from "./chunk-ZWB7JGAJ.js";
11
+ import {
12
+ createTree
13
+ } from "./chunk-Y7FTBBYX.js";
14
+ import {
15
+ createMeasureCache,
16
+ createVirtual
17
+ } from "./chunk-IY6LJU3L.js";
18
+ import {
19
+ aabbFromOBB,
20
+ createGraph,
21
+ floatingAnchor,
22
+ getBezierPath,
23
+ getEdgePosition,
24
+ getNodeIntersection,
25
+ inferSide,
26
+ nearestSide,
27
+ obbContainsPoint,
28
+ obbCorners,
29
+ pointsToPath,
30
+ pointsToRoundedPath,
31
+ resolveEdgeEndpoint,
32
+ routeOrthogonal
33
+ } from "./chunk-7FA2TBSZ.js";
34
+ import {
35
+ createCalendar,
36
+ detectConflicts,
37
+ isAvailable
38
+ } from "./chunk-AB3RLBLW.js";
39
+ import {
40
+ CALENDAR_PREFIX,
41
+ FORM_META_PREFIX,
42
+ GRAPH_PREFIX,
43
+ TABLE_PREFIX,
44
+ TREE_PREFIX,
45
+ listReservedPrefixes,
46
+ reservePrefix
47
+ } from "./chunk-5CCD5Q4B.js";
48
+ import {
49
+ Batch,
50
+ ComputedEngine,
51
+ Store,
52
+ SubscriptionEngine,
53
+ Transaction
54
+ } from "./chunk-GEMALROQ.js";
55
+
56
+ // src/Core.ts
57
+ var CoreImpl = class {
58
+ store = new Store();
59
+ subscriptions = new SubscriptionEngine();
60
+ batch_ = new Batch();
61
+ transaction_ = new Transaction();
62
+ computed_ = new ComputedEngine();
63
+ middlewares = [];
64
+ // ── Middleware ──
65
+ use(middleware) {
66
+ this.middlewares.push(middleware);
67
+ return () => {
68
+ const idx = this.middlewares.indexOf(middleware);
69
+ if (idx !== -1) this.middlewares.splice(idx, 1);
70
+ };
71
+ }
72
+ dispatchWrite(event) {
73
+ let idx = 0;
74
+ const chain = (ev) => {
75
+ if (idx < this.middlewares.length) {
76
+ const mw = this.middlewares[idx++];
77
+ mw(ev, chain);
78
+ } else {
79
+ this.commitWrite(ev);
80
+ }
81
+ };
82
+ chain(event);
83
+ }
84
+ commitWrite(event) {
85
+ this.store.set(event.path, event.value);
86
+ }
87
+ // ── Public API ──
88
+ get(path) {
89
+ return this.store.get(path);
90
+ }
91
+ set(path, value) {
92
+ if (this.transaction_.isActive) {
93
+ this.transaction_.stage(path, value, this.store.get(path));
94
+ return;
95
+ }
96
+ const oldValue = this.store.get(path);
97
+ if (Object.is(oldValue, value)) return;
98
+ this.dispatchWrite({ path, value, oldValue, source: "user" });
99
+ const computedChanges = this.propagateComputed(/* @__PURE__ */ new Set([path]));
100
+ if (this.batch_.isActive) {
101
+ this.batch_.enqueue(path, value);
102
+ for (const [cp, cv] of computedChanges) {
103
+ this.batch_.enqueue(cp, cv);
104
+ }
105
+ return;
106
+ }
107
+ this.subscriptions.notify(path, value);
108
+ this.subscriptions.notifyMany(computedChanges);
109
+ }
110
+ subscribe(path, cb) {
111
+ return this.subscriptions.subscribe(path, cb);
112
+ }
113
+ batch(fn) {
114
+ this.batch_.start();
115
+ try {
116
+ fn();
117
+ } finally {
118
+ const changes = this.batch_.end();
119
+ if (changes) {
120
+ this.subscriptions.notifyMany(changes);
121
+ }
122
+ }
123
+ }
124
+ transaction(fn) {
125
+ this.batch_.start();
126
+ this.transaction_.start();
127
+ try {
128
+ fn();
129
+ const staged = this.transaction_.getStaged();
130
+ const approved = [];
131
+ const origCommit = this.commitWrite.bind(this);
132
+ this.commitWrite = (ev) => {
133
+ approved.push({ path: ev.path, value: ev.value });
134
+ };
135
+ try {
136
+ for (const write of staged) {
137
+ if (Object.is(write.value, write.prevValue)) continue;
138
+ this.dispatchWrite({
139
+ path: write.path,
140
+ value: write.value,
141
+ oldValue: write.prevValue,
142
+ source: "transaction"
143
+ });
144
+ }
145
+ } finally {
146
+ this.commitWrite = origCommit;
147
+ }
148
+ const changes = /* @__PURE__ */ new Map();
149
+ for (const { path, value } of approved) {
150
+ this.store.set(path, value);
151
+ changes.set(path, value);
152
+ }
153
+ this.transaction_.complete();
154
+ const computedChanges = this.propagateComputed(new Set(changes.keys()));
155
+ for (const [path, value] of changes) {
156
+ this.batch_.enqueue(path, value);
157
+ }
158
+ for (const [path, value] of computedChanges) {
159
+ this.batch_.enqueue(path, value);
160
+ }
161
+ } catch (e) {
162
+ this.transaction_.rollback();
163
+ throw e;
164
+ } finally {
165
+ const batchedChanges = this.batch_.end();
166
+ if (batchedChanges) {
167
+ this.subscriptions.notifyMany(batchedChanges);
168
+ }
169
+ }
170
+ }
171
+ computed(target, deps, fn) {
172
+ this.computed_.register(target, deps, fn);
173
+ const depValues = deps.map((d) => this.store.get(d));
174
+ const value = fn(...depValues);
175
+ const oldValue = this.store.get(target);
176
+ this.dispatchWrite({
177
+ path: target,
178
+ value,
179
+ oldValue,
180
+ source: "computed"
181
+ });
182
+ if (!Object.is(oldValue, value)) {
183
+ this.subscriptions.notify(target, value);
184
+ }
185
+ }
186
+ // ── Snapshot / Restore ──
187
+ snapshot() {
188
+ const result = {};
189
+ for (const path of this.store.paths()) {
190
+ result[path] = this.store.get(path);
191
+ }
192
+ return result;
193
+ }
194
+ restore(snap) {
195
+ this.batch_.start();
196
+ try {
197
+ for (const [path, value] of Object.entries(snap)) {
198
+ const oldValue = this.store.get(path);
199
+ if (!Object.is(oldValue, value)) {
200
+ this.dispatchWrite({ path, value, oldValue, source: "restore" });
201
+ this.batch_.enqueue(path, value);
202
+ }
203
+ }
204
+ } finally {
205
+ const changes = this.batch_.end();
206
+ if (changes) {
207
+ this.subscriptions.notifyMany(changes);
208
+ }
209
+ }
210
+ }
211
+ // ── Internal helpers ──
212
+ propagateComputed(changedPaths) {
213
+ const rawChanges = this.computed_.propagateRaw(changedPaths, this.store);
214
+ const dispatched = /* @__PURE__ */ new Map();
215
+ for (const [path, { value, oldValue }] of rawChanges) {
216
+ this.dispatchWrite({ path, value, oldValue, source: "computed" });
217
+ dispatched.set(path, value);
218
+ }
219
+ return dispatched;
220
+ }
221
+ };
222
+ function createCore() {
223
+ return new CoreImpl();
224
+ }
225
+
226
+ // src/middleware/logger.ts
227
+ function loggerMiddleware(options = {}) {
228
+ const log = options.log ?? ((msg, ev) => console.log(msg, ev.path, ev.value));
229
+ const filter = options.filter;
230
+ return (event, next) => {
231
+ if (filter && !filter(event)) {
232
+ next(event);
233
+ return;
234
+ }
235
+ log(`[skygraph:${event.source}]`, event);
236
+ next(event);
237
+ };
238
+ }
239
+
240
+ // src/middleware/freeze.ts
241
+ function freezeMiddleware(frozenPaths) {
242
+ return (event, next) => {
243
+ for (const prefix of frozenPaths) {
244
+ if (event.path === prefix || event.path.startsWith(prefix + ".")) {
245
+ return;
246
+ }
247
+ }
248
+ next(event);
249
+ };
250
+ }
251
+
252
+ // src/middleware/persistence.ts
253
+ function persistenceMiddleware(options = {}) {
254
+ const storageKey = options.key ?? "skygraph:state";
255
+ const storage = options.storage ?? (typeof localStorage !== "undefined" ? localStorage : null);
256
+ const paths = options.paths;
257
+ const debounceMs = options.debounce ?? 100;
258
+ let pending = {};
259
+ let timer = null;
260
+ function flush() {
261
+ if (!storage) return;
262
+ const existing = storage.getItem(storageKey);
263
+ let data = {};
264
+ if (existing) {
265
+ try {
266
+ data = JSON.parse(existing);
267
+ } catch {
268
+ }
269
+ }
270
+ Object.assign(data, pending);
271
+ storage.setItem(storageKey, JSON.stringify(data));
272
+ pending = {};
273
+ timer = null;
274
+ }
275
+ return (event, next) => {
276
+ next(event);
277
+ if (paths && !paths.some((p) => event.path === p || event.path.startsWith(p + "."))) {
278
+ return;
279
+ }
280
+ pending[event.path] = event.value;
281
+ if (timer === null) {
282
+ timer = setTimeout(flush, debounceMs);
283
+ }
284
+ };
285
+ }
286
+
287
+ // src/middleware/validation.ts
288
+ function validationMiddleware(optionsOrValidators) {
289
+ const isOptions = "validators" in optionsOrValidators;
290
+ const validators = isOptions ? optionsOrValidators.validators : optionsOrValidators;
291
+ const onReject = isOptions ? optionsOrValidators.onReject : void 0;
292
+ return (event, next) => {
293
+ const validator = validators[event.path];
294
+ if (validator) {
295
+ const result = validator(event);
296
+ if (result === false || typeof result === "string") {
297
+ onReject?.(event, typeof result === "string" ? result : "Validation failed");
298
+ return;
299
+ }
300
+ }
301
+ next(event);
302
+ };
303
+ }
304
+
305
+ // src/plugins/history.ts
306
+ function createHistory(core, options = {}) {
307
+ const maxEntries = options.maxEntries ?? 100;
308
+ const groupWindow = options.groupWindow ?? 0;
309
+ const filter = options.filter;
310
+ const entries = [];
311
+ let cursor = -1;
312
+ let travelling = false;
313
+ let groupTimer = null;
314
+ let pendingPatches = [];
315
+ function flushGroup() {
316
+ if (pendingPatches.length === 0) return;
317
+ const entry = {
318
+ timestamp: Date.now(),
319
+ patches: [...pendingPatches]
320
+ };
321
+ pendingPatches = [];
322
+ if (cursor < entries.length - 1) {
323
+ entries.splice(cursor + 1);
324
+ }
325
+ entries.push(entry);
326
+ cursor++;
327
+ if (entries.length > maxEntries) {
328
+ entries.shift();
329
+ cursor--;
330
+ }
331
+ groupTimer = null;
332
+ }
333
+ const middleware = (event, next) => {
334
+ next(event);
335
+ if (travelling) return;
336
+ if (event.source === "computed") return;
337
+ if (filter && !filter(event)) return;
338
+ pendingPatches.push({
339
+ path: event.path,
340
+ value: event.value,
341
+ oldValue: event.oldValue
342
+ });
343
+ if (groupWindow > 0) {
344
+ if (groupTimer === null) {
345
+ groupTimer = setTimeout(flushGroup, groupWindow);
346
+ }
347
+ } else {
348
+ flushGroup();
349
+ }
350
+ };
351
+ const unsub = core.use(middleware);
352
+ function applyPatches(patches, direction) {
353
+ travelling = true;
354
+ try {
355
+ core.batch(() => {
356
+ if (direction === "undo") {
357
+ for (let i = patches.length - 1; i >= 0; i--) {
358
+ core.set(patches[i].path, patches[i].oldValue);
359
+ }
360
+ } else {
361
+ for (const patch of patches) {
362
+ core.set(patch.path, patch.value);
363
+ }
364
+ }
365
+ });
366
+ } finally {
367
+ travelling = false;
368
+ }
369
+ }
370
+ return {
371
+ get entries() {
372
+ return entries;
373
+ },
374
+ get cursor() {
375
+ return cursor;
376
+ },
377
+ get canUndo() {
378
+ return cursor >= 0;
379
+ },
380
+ get canRedo() {
381
+ return cursor < entries.length - 1;
382
+ },
383
+ undo() {
384
+ if (cursor < 0) return;
385
+ flushGroup();
386
+ applyPatches(entries[cursor].patches, "undo");
387
+ cursor--;
388
+ },
389
+ redo() {
390
+ if (cursor >= entries.length - 1) return;
391
+ flushGroup();
392
+ cursor++;
393
+ applyPatches(entries[cursor].patches, "redo");
394
+ },
395
+ jumpTo(index) {
396
+ if (index < -1 || index >= entries.length) return;
397
+ flushGroup();
398
+ while (cursor > index) {
399
+ applyPatches(entries[cursor].patches, "undo");
400
+ cursor--;
401
+ }
402
+ while (cursor < index) {
403
+ cursor++;
404
+ applyPatches(entries[cursor].patches, "redo");
405
+ }
406
+ },
407
+ clear() {
408
+ entries.length = 0;
409
+ cursor = -1;
410
+ pendingPatches = [];
411
+ if (groupTimer !== null) {
412
+ clearTimeout(groupTimer);
413
+ groupTimer = null;
414
+ }
415
+ },
416
+ destroy() {
417
+ this.clear();
418
+ unsub();
419
+ }
420
+ };
421
+ }
422
+
423
+ // src/typed.ts
424
+ function createTypedCore(core) {
425
+ return {
426
+ get: core.get.bind(core),
427
+ set: core.set.bind(core),
428
+ subscribe: core.subscribe.bind(core),
429
+ batch: core.batch.bind(core),
430
+ transaction: core.transaction.bind(core),
431
+ computed: core.computed.bind(core),
432
+ raw: core
433
+ };
434
+ }
435
+ export {
436
+ CALENDAR_PREFIX,
437
+ FORM_META_PREFIX,
438
+ GRAPH_PREFIX,
439
+ TABLE_PREFIX,
440
+ TREE_PREFIX,
441
+ aabbFromOBB,
442
+ computeAggregate,
443
+ createCalendar,
444
+ createCore,
445
+ createForm,
446
+ createGraph,
447
+ createHistory,
448
+ createMeasureCache,
449
+ createTable,
450
+ createTree,
451
+ createTypedCore,
452
+ createVirtual,
453
+ detectConflicts,
454
+ floatingAnchor,
455
+ freezeMiddleware,
456
+ getBezierPath,
457
+ getEdgePosition,
458
+ getNodeIntersection,
459
+ inferSide,
460
+ isAvailable,
461
+ listReservedPrefixes,
462
+ loggerMiddleware,
463
+ matchesColumnFilter,
464
+ matchesOperator,
465
+ nearestSide,
466
+ obbContainsPoint,
467
+ obbCorners,
468
+ persistenceMiddleware,
469
+ pointsToPath,
470
+ pointsToRoundedPath,
471
+ reservePrefix,
472
+ resolveEdgeEndpoint,
473
+ resolveOperator,
474
+ routeOrthogonal,
475
+ validationMiddleware
476
+ };
477
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Core.ts","../src/middleware/logger.ts","../src/middleware/freeze.ts","../src/middleware/persistence.ts","../src/middleware/validation.ts","../src/plugins/history.ts","../src/typed.ts"],"sourcesContent":["import { Store } from './runtime/Store'\nimport { SubscriptionEngine } from './runtime/SubscriptionEngine'\nimport { Batch } from './runtime/Batch'\nimport { Transaction } from './runtime/Transaction'\nimport { ComputedEngine } from './runtime/ComputedEngine'\nimport type { Core, Middleware, WriteEvent, NextFn } from './types'\n\nclass CoreImpl implements Core {\n private store = new Store()\n private subscriptions = new SubscriptionEngine()\n private batch_ = new Batch()\n private transaction_ = new Transaction()\n private computed_ = new ComputedEngine()\n\n private middlewares: Middleware[] = []\n\n // ── Middleware ──\n\n use(middleware: Middleware): () => void {\n this.middlewares.push(middleware)\n return () => {\n const idx = this.middlewares.indexOf(middleware)\n if (idx !== -1) this.middlewares.splice(idx, 1)\n }\n }\n\n private dispatchWrite(event: WriteEvent): void {\n let idx = 0\n const chain: NextFn = (ev: WriteEvent) => {\n if (idx < this.middlewares.length) {\n const mw = this.middlewares[idx++]\n mw(ev, chain)\n } else {\n this.commitWrite(ev)\n }\n }\n chain(event)\n }\n\n private commitWrite(event: WriteEvent): void {\n this.store.set(event.path, event.value)\n }\n\n // ── Public API ──\n\n get(path: string): unknown {\n return this.store.get(path)\n }\n\n set(path: string, value: unknown): void {\n if (this.transaction_.isActive) {\n this.transaction_.stage(path, value, this.store.get(path))\n return\n }\n\n const oldValue = this.store.get(path)\n if (Object.is(oldValue, value)) return\n\n this.dispatchWrite({ path, value, oldValue, source: 'user' })\n\n const computedChanges = this.propagateComputed(new Set([path]))\n\n if (this.batch_.isActive) {\n this.batch_.enqueue(path, value)\n for (const [cp, cv] of computedChanges) {\n this.batch_.enqueue(cp, cv)\n }\n return\n }\n\n this.subscriptions.notify(path, value)\n this.subscriptions.notifyMany(computedChanges)\n }\n\n subscribe(path: string, cb: (value: unknown) => void): () => void {\n return this.subscriptions.subscribe(path, cb)\n }\n\n batch(fn: () => void): void {\n this.batch_.start()\n try {\n fn()\n } finally {\n const changes = this.batch_.end()\n if (changes) {\n this.subscriptions.notifyMany(changes)\n }\n }\n }\n\n transaction(fn: () => void): void {\n this.batch_.start()\n this.transaction_.start()\n try {\n fn()\n const staged = this.transaction_.getStaged()\n\n // Pass all writes through middleware first, collecting approved ones.\n // dispatchWrite normally commits to store, so we temporarily redirect\n // commits to a pending list and only apply them atomically if all succeed.\n const approved: Array<{ path: string; value: unknown }> = []\n const origCommit = this.commitWrite.bind(this)\n this.commitWrite = (ev: WriteEvent) => {\n approved.push({ path: ev.path, value: ev.value })\n }\n\n try {\n for (const write of staged) {\n if (Object.is(write.value, write.prevValue)) continue\n this.dispatchWrite({\n path: write.path,\n value: write.value,\n oldValue: write.prevValue,\n source: 'transaction',\n })\n }\n } finally {\n this.commitWrite = origCommit\n }\n\n // All middleware passed — atomically apply to store\n const changes = new Map<string, unknown>()\n for (const { path, value } of approved) {\n this.store.set(path, value)\n changes.set(path, value)\n }\n\n this.transaction_.complete()\n\n const computedChanges = this.propagateComputed(new Set(changes.keys()))\n\n for (const [path, value] of changes) {\n this.batch_.enqueue(path, value)\n }\n for (const [path, value] of computedChanges) {\n this.batch_.enqueue(path, value)\n }\n } catch (e) {\n this.transaction_.rollback()\n throw e\n } finally {\n const batchedChanges = this.batch_.end()\n if (batchedChanges) {\n this.subscriptions.notifyMany(batchedChanges)\n }\n }\n }\n\n computed(\n target: string,\n deps: string[],\n fn: (...values: unknown[]) => unknown,\n ): void {\n this.computed_.register(target, deps, fn)\n const depValues = deps.map((d) => this.store.get(d))\n const value = fn(...depValues)\n const oldValue = this.store.get(target)\n this.dispatchWrite({\n path: target,\n value,\n oldValue,\n source: 'computed',\n })\n\n if (!Object.is(oldValue, value)) {\n this.subscriptions.notify(target, value)\n }\n }\n\n // ── Snapshot / Restore ──\n\n snapshot(): Record<string, unknown> {\n const result: Record<string, unknown> = {}\n for (const path of this.store.paths()) {\n result[path] = this.store.get(path)\n }\n return result\n }\n\n restore(snap: Record<string, unknown>): void {\n this.batch_.start()\n try {\n for (const [path, value] of Object.entries(snap)) {\n const oldValue = this.store.get(path)\n if (!Object.is(oldValue, value)) {\n this.dispatchWrite({ path, value, oldValue, source: 'restore' })\n this.batch_.enqueue(path, value)\n }\n }\n } finally {\n const changes = this.batch_.end()\n if (changes) {\n this.subscriptions.notifyMany(changes)\n }\n }\n }\n\n // ── Internal helpers ──\n\n private propagateComputed(changedPaths: Set<string>): Map<string, unknown> {\n const rawChanges = this.computed_.propagateRaw(changedPaths, this.store)\n const dispatched = new Map<string, unknown>()\n\n for (const [path, { value, oldValue }] of rawChanges) {\n this.dispatchWrite({ path, value, oldValue, source: 'computed' })\n dispatched.set(path, value)\n }\n\n return dispatched\n }\n}\n\nexport function createCore(): Core {\n return new CoreImpl()\n}\n","import type { Middleware, WriteEvent, NextFn } from '../types'\n\nexport interface LoggerOptions {\n filter?: (event: WriteEvent) => boolean\n log?: (message: string, event: WriteEvent) => void\n}\n\nexport function loggerMiddleware(options: LoggerOptions = {}): Middleware {\n const log = options.log ?? ((msg, ev) => console.log(msg, ev.path, ev.value))\n const filter = options.filter\n\n return (event: WriteEvent, next: NextFn) => {\n if (filter && !filter(event)) {\n next(event)\n return\n }\n log(`[skygraph:${event.source}]`, event)\n next(event)\n }\n}\n","import type { Middleware, WriteEvent, NextFn } from '../types'\n\n/**\n * Prevents writes to specified path prefixes.\n * Useful for making parts of the store read-only.\n */\nexport function freezeMiddleware(frozenPaths: string[]): Middleware {\n return (event: WriteEvent, next: NextFn) => {\n for (const prefix of frozenPaths) {\n if (event.path === prefix || event.path.startsWith(prefix + '.')) {\n return\n }\n }\n next(event)\n }\n}\n","import type { Middleware, WriteEvent, NextFn } from '../types'\n\nexport interface PersistenceOptions {\n key?: string\n paths?: string[]\n storage?: {\n getItem(key: string): string | null\n setItem(key: string, value: string): void\n }\n debounce?: number\n}\n\n/**\n * Persists selected paths to a storage backend (localStorage by default).\n * Debounced to avoid excessive writes.\n */\nexport function persistenceMiddleware(options: PersistenceOptions = {}): Middleware {\n const storageKey = options.key ?? 'skygraph:state'\n const storage = options.storage ?? (typeof localStorage !== 'undefined' ? localStorage : null)\n const paths = options.paths\n const debounceMs = options.debounce ?? 100\n\n let pending: Record<string, unknown> = {}\n let timer: ReturnType<typeof setTimeout> | null = null\n\n function flush() {\n if (!storage) return\n const existing = storage.getItem(storageKey)\n let data: Record<string, unknown> = {}\n if (existing) {\n try {\n data = JSON.parse(existing)\n } catch {\n /* corrupted, start fresh */\n }\n }\n Object.assign(data, pending)\n storage.setItem(storageKey, JSON.stringify(data))\n pending = {}\n timer = null\n }\n\n return (event: WriteEvent, next: NextFn) => {\n next(event)\n\n if (paths && !paths.some((p) => event.path === p || event.path.startsWith(p + '.'))) {\n return\n }\n\n pending[event.path] = event.value\n\n if (timer === null) {\n timer = setTimeout(flush, debounceMs)\n }\n }\n}\n","import type { Middleware, WriteEvent, NextFn } from '../types'\n\nexport type Validator = (event: WriteEvent) => boolean | string\n\nexport interface ValidationMiddlewareOptions {\n validators: Record<string, Validator>\n onReject?: (event: WriteEvent, reason: string) => void\n}\n\n/**\n * Validates writes against a map of path -> validator.\n * If the validator returns false or a string (error message),\n * the write is rejected and onReject is called (if provided).\n */\nexport function validationMiddleware(\n optionsOrValidators: ValidationMiddlewareOptions | Record<string, Validator>,\n): Middleware {\n const isOptions = 'validators' in optionsOrValidators\n const validators: Record<string, Validator> = isOptions\n ? (optionsOrValidators as ValidationMiddlewareOptions).validators\n : (optionsOrValidators as Record<string, Validator>)\n const onReject = isOptions\n ? (optionsOrValidators as ValidationMiddlewareOptions).onReject\n : undefined\n\n return (event: WriteEvent, next: NextFn) => {\n const validator = validators[event.path]\n if (validator) {\n const result = validator(event)\n if (result === false || typeof result === 'string') {\n onReject?.(event, typeof result === 'string' ? result : 'Validation failed')\n return\n }\n }\n next(event)\n }\n}\n","import type { Core, Middleware, WriteEvent, NextFn } from '../types'\n\nexport interface HistoryEntry {\n timestamp: number\n patches: ReadonlyArray<{ path: string; value: unknown; oldValue: unknown }>\n}\n\nexport interface HistoryPlugin {\n readonly entries: ReadonlyArray<HistoryEntry>\n readonly cursor: number\n readonly canUndo: boolean\n readonly canRedo: boolean\n\n undo(): void\n redo(): void\n jumpTo(index: number): void\n clear(): void\n destroy(): void\n}\n\nexport interface HistoryOptions {\n maxEntries?: number\n /** Group multiple writes within this window (ms) into a single entry */\n groupWindow?: number\n filter?: (event: WriteEvent) => boolean\n}\n\nexport function createHistory(core: Core, options: HistoryOptions = {}): HistoryPlugin {\n const maxEntries = options.maxEntries ?? 100\n const groupWindow = options.groupWindow ?? 0\n const filter = options.filter\n\n const entries: HistoryEntry[] = []\n let cursor = -1\n let travelling = false\n let groupTimer: ReturnType<typeof setTimeout> | null = null\n let pendingPatches: HistoryEntry['patches'][number][] = []\n\n function flushGroup() {\n if (pendingPatches.length === 0) return\n const entry: HistoryEntry = {\n timestamp: Date.now(),\n patches: [...pendingPatches],\n }\n pendingPatches = []\n\n if (cursor < entries.length - 1) {\n entries.splice(cursor + 1)\n }\n\n entries.push(entry)\n cursor++\n if (entries.length > maxEntries) {\n entries.shift()\n cursor--\n }\n\n groupTimer = null\n }\n\n const middleware: Middleware = (event: WriteEvent, next: NextFn) => {\n next(event)\n\n if (travelling) return\n if (event.source === 'computed') return\n if (filter && !filter(event)) return\n\n pendingPatches.push({\n path: event.path,\n value: event.value,\n oldValue: event.oldValue,\n })\n\n if (groupWindow > 0) {\n if (groupTimer === null) {\n groupTimer = setTimeout(flushGroup, groupWindow)\n }\n } else {\n flushGroup()\n }\n }\n\n const unsub = core.use(middleware)\n\n function applyPatches(patches: HistoryEntry['patches'], direction: 'undo' | 'redo') {\n travelling = true\n try {\n core.batch(() => {\n if (direction === 'undo') {\n for (let i = patches.length - 1; i >= 0; i--) {\n core.set(patches[i].path, patches[i].oldValue)\n }\n } else {\n for (const patch of patches) {\n core.set(patch.path, patch.value)\n }\n }\n })\n } finally {\n travelling = false\n }\n }\n\n return {\n get entries() {\n return entries as ReadonlyArray<HistoryEntry>\n },\n get cursor() {\n return cursor\n },\n get canUndo() {\n return cursor >= 0\n },\n get canRedo() {\n return cursor < entries.length - 1\n },\n\n undo() {\n if (cursor < 0) return\n flushGroup()\n applyPatches(entries[cursor].patches, 'undo')\n cursor--\n },\n\n redo() {\n if (cursor >= entries.length - 1) return\n flushGroup()\n cursor++\n applyPatches(entries[cursor].patches, 'redo')\n },\n\n jumpTo(index: number) {\n if (index < -1 || index >= entries.length) return\n flushGroup()\n\n while (cursor > index) {\n applyPatches(entries[cursor].patches, 'undo')\n cursor--\n }\n while (cursor < index) {\n cursor++\n applyPatches(entries[cursor].patches, 'redo')\n }\n },\n\n clear() {\n entries.length = 0\n cursor = -1\n pendingPatches = []\n if (groupTimer !== null) {\n clearTimeout(groupTimer)\n groupTimer = null\n }\n },\n\n destroy() {\n this.clear()\n unsub()\n },\n }\n}\n","import type { Core } from './types'\n\n/**\n * Utility types for path-based type inference.\n * These provide compile-time type safety over the untyped Core runtime.\n */\n\ntype Primitive = string | number | boolean | null | undefined\n\n/**\n * Extracts dot-notation paths from a nested object type (max 3 levels deep).\n * Example: Path<{user: {name: string}}> = \"user\" | \"user.name\"\n */\nexport type Path<T> = T extends Primitive\n ? never\n : {\n [K in keyof T & string]: T[K] extends Primitive\n ? K\n : T[K] extends Record<string, unknown>\n ?\n | K\n | `${K}.${keyof T[K] & string}`\n | {\n [L in keyof T[K] & string]: T[K][L] extends Record<\n string,\n unknown\n >\n ? `${K}.${L}.${keyof T[K][L] & string}`\n : never\n }[keyof T[K] & string]\n : K\n }[keyof T & string]\n\n/**\n * Resolves the value type at a given dot-notation path (max 3 levels).\n */\nexport type PathValue<T, P extends string> = P extends keyof T\n ? T[P]\n : P extends `${infer K}.${infer Rest}`\n ? K extends keyof T\n ? Rest extends keyof T[K]\n ? T[K][Rest]\n : Rest extends `${infer L}.${infer M}`\n ? L extends keyof T[K]\n ? M extends keyof T[K][L]\n ? T[K][L][M]\n : unknown\n : unknown\n : unknown\n : unknown\n : unknown\n\n/**\n * Type-safe wrapper over Core.\n * Compile-time only — runtime behavior is identical to Core.\n */\nexport interface TypedCore<T> {\n get<K extends Path<T>>(path: K): PathValue<T, K>\n set<K extends Path<T>>(path: K, value: PathValue<T, K>): void\n subscribe<K extends Path<T>>(\n path: K,\n cb: (value: PathValue<T, K>) => void\n ): () => void\n batch(fn: () => void): void\n transaction(fn: () => void): void\n computed<K extends Path<T>>(\n target: K,\n deps: Path<T>[],\n fn: (...values: unknown[]) => PathValue<T, K>\n ): void\n /** Access the untyped core underneath */\n raw: Core\n}\n\n/**\n * Creates a type-safe wrapper around an existing Core instance.\n * No runtime overhead — just type narrowing.\n */\nexport function createTypedCore<T>(core: Core): TypedCore<T> {\n return {\n get: core.get.bind(core) as TypedCore<T>['get'],\n set: core.set.bind(core) as TypedCore<T>['set'],\n subscribe: core.subscribe.bind(core) as TypedCore<T>['subscribe'],\n batch: core.batch.bind(core),\n transaction: core.transaction.bind(core),\n computed: core.computed.bind(core) as TypedCore<T>['computed'],\n raw: core,\n }\n}\n"],"mappings":"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","names":[]}