@json-render/core 0.8.0 → 0.9.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/dist/index.js CHANGED
@@ -47,6 +47,7 @@ __export(index_exports, {
47
47
  createJsonRenderTransform: () => createJsonRenderTransform,
48
48
  createMixedStreamParser: () => createMixedStreamParser,
49
49
  createSpecStreamCompiler: () => createSpecStreamCompiler,
50
+ createStateStore: () => createStateStore,
50
51
  defineCatalog: () => defineCatalog,
51
52
  defineSchema: () => defineSchema,
52
53
  evaluateVisibility: () => evaluateVisibility,
@@ -629,6 +630,82 @@ function pipeJsonRender(stream) {
629
630
  );
630
631
  }
631
632
 
633
+ // src/state-store.ts
634
+ function immutableSetByPath(root, path, value) {
635
+ const segments = parseJsonPointer(path);
636
+ if (segments.length === 0) return root;
637
+ const result = { ...root };
638
+ let current = result;
639
+ for (let i = 0; i < segments.length - 1; i++) {
640
+ const seg = segments[i];
641
+ const child = current[seg];
642
+ if (Array.isArray(child)) {
643
+ current[seg] = [...child];
644
+ } else if (child !== null && typeof child === "object") {
645
+ current[seg] = { ...child };
646
+ } else {
647
+ const nextSeg = segments[i + 1];
648
+ current[seg] = nextSeg !== void 0 && /^\d+$/.test(nextSeg) ? [] : {};
649
+ }
650
+ current = current[seg];
651
+ }
652
+ const lastSeg = segments[segments.length - 1];
653
+ if (Array.isArray(current)) {
654
+ if (lastSeg === "-") {
655
+ current.push(value);
656
+ } else {
657
+ current[parseInt(lastSeg, 10)] = value;
658
+ }
659
+ } else {
660
+ current[lastSeg] = value;
661
+ }
662
+ return result;
663
+ }
664
+ function createStateStore(initialState = {}) {
665
+ let state = { ...initialState };
666
+ const listeners = /* @__PURE__ */ new Set();
667
+ function notify() {
668
+ for (const listener of listeners) {
669
+ listener();
670
+ }
671
+ }
672
+ return {
673
+ get(path) {
674
+ return getByPath(state, path);
675
+ },
676
+ set(path, value) {
677
+ if (getByPath(state, path) === value) return;
678
+ state = immutableSetByPath(state, path, value);
679
+ notify();
680
+ },
681
+ update(updates) {
682
+ let changed = false;
683
+ let next = state;
684
+ for (const [path, value] of Object.entries(updates)) {
685
+ if (getByPath(next, path) !== value) {
686
+ next = immutableSetByPath(next, path, value);
687
+ changed = true;
688
+ }
689
+ }
690
+ if (!changed) return;
691
+ state = next;
692
+ notify();
693
+ },
694
+ getSnapshot() {
695
+ return state;
696
+ },
697
+ getServerSnapshot() {
698
+ return state;
699
+ },
700
+ subscribe(listener) {
701
+ listeners.add(listener);
702
+ return () => {
703
+ listeners.delete(listener);
704
+ };
705
+ }
706
+ };
707
+ }
708
+
632
709
  // src/visibility.ts
633
710
  var import_zod2 = require("zod");
634
711
  var numericOrStateRef = import_zod2.z.union([
@@ -2015,7 +2092,7 @@ function formatZodType(schema) {
2015
2092
  }
2016
2093
  case "ZodArray":
2017
2094
  case "array": {
2018
- const inner = def.type ?? def.element;
2095
+ const inner = typeof def.element === "object" ? def.element : typeof def.type === "object" ? def.type : void 0;
2019
2096
  return inner ? `Array<${formatZodType(inner)}>` : "Array<unknown>";
2020
2097
  }
2021
2098
  case "ZodObject":
@@ -2189,6 +2266,7 @@ Remember: Output /root first, then interleave /elements and /state patches so th
2189
2266
  createJsonRenderTransform,
2190
2267
  createMixedStreamParser,
2191
2268
  createSpecStreamCompiler,
2269
+ createStateStore,
2192
2270
  defineCatalog,
2193
2271
  defineSchema,
2194
2272
  evaluateVisibility,