@getforma/core 1.0.9 → 1.1.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 (64) hide show
  1. package/README.md +1 -1
  2. package/dist/chunk-263HW3KN.cjs +35 -0
  3. package/dist/chunk-263HW3KN.cjs.map +1 -0
  4. package/dist/chunk-2QQBKQIF.js +30 -0
  5. package/dist/chunk-2QQBKQIF.js.map +1 -0
  6. package/dist/{chunk-6FW5E54W.cjs → chunk-2Y5US35K.cjs} +127 -103
  7. package/dist/chunk-2Y5US35K.cjs.map +1 -0
  8. package/dist/{chunk-3G7ET4O5.js → chunk-INNOI6TG.js} +121 -94
  9. package/dist/chunk-INNOI6TG.js.map +1 -0
  10. package/dist/{chunk-T33QUD2Y.cjs → chunk-JRQNDXX7.cjs} +43 -43
  11. package/dist/{chunk-T33QUD2Y.cjs.map → chunk-JRQNDXX7.cjs.map} +1 -1
  12. package/dist/{chunk-AFRFF7XL.js → chunk-MIOMT2CB.js} +4 -4
  13. package/dist/{chunk-AFRFF7XL.js.map → chunk-MIOMT2CB.js.map} +1 -1
  14. package/dist/chunk-W7OUWVRA.cjs +106 -0
  15. package/dist/chunk-W7OUWVRA.cjs.map +1 -0
  16. package/dist/chunk-XLVBYXOU.js +100 -0
  17. package/dist/chunk-XLVBYXOU.js.map +1 -0
  18. package/dist/forma-runtime-csp.js +92 -6
  19. package/dist/forma-runtime.js +138 -12
  20. package/dist/formajs-runtime-hardened.global.js +92 -6
  21. package/dist/formajs-runtime-hardened.global.js.map +1 -1
  22. package/dist/formajs-runtime.global.js +138 -12
  23. package/dist/formajs-runtime.global.js.map +1 -1
  24. package/dist/formajs.global.js +192 -95
  25. package/dist/formajs.global.js.map +1 -1
  26. package/dist/http.cjs +11 -11
  27. package/dist/http.js +2 -2
  28. package/dist/index.cjs +66 -66
  29. package/dist/index.d.cts +11 -25
  30. package/dist/index.d.ts +11 -25
  31. package/dist/index.js +6 -6
  32. package/dist/{resource-DeEzxUz6.d.cts → resource-D6HfVgiA.d.cts} +7 -2
  33. package/dist/{resource-BHsgURy0.d.ts → resource-ljs2X5NM.d.ts} +7 -2
  34. package/dist/runtime-hardened.cjs +93 -5
  35. package/dist/runtime-hardened.cjs.map +1 -1
  36. package/dist/runtime-hardened.js +93 -5
  37. package/dist/runtime-hardened.js.map +1 -1
  38. package/dist/runtime.cjs +47 -31
  39. package/dist/runtime.cjs.map +1 -1
  40. package/dist/runtime.js +21 -5
  41. package/dist/runtime.js.map +1 -1
  42. package/dist/server.cjs +7 -7
  43. package/dist/server.d.cts +2 -2
  44. package/dist/server.d.ts +2 -2
  45. package/dist/server.js +2 -2
  46. package/dist/{signal-C9v4akyJ.d.cts → signal-CRBJYQ6B.d.cts} +0 -8
  47. package/dist/{signal-C9v4akyJ.d.ts → signal-CRBJYQ6B.d.ts} +0 -8
  48. package/dist/ssr/index.cjs +23 -42
  49. package/dist/ssr/index.cjs.map +1 -1
  50. package/dist/ssr/index.js +23 -42
  51. package/dist/ssr/index.js.map +1 -1
  52. package/dist/tc39-compat.cjs +3 -6
  53. package/dist/tc39-compat.cjs.map +1 -1
  54. package/dist/tc39-compat.d.cts +1 -1
  55. package/dist/tc39-compat.d.ts +1 -1
  56. package/dist/tc39-compat.js +1 -4
  57. package/dist/tc39-compat.js.map +1 -1
  58. package/package.json +2 -2
  59. package/dist/chunk-3G7ET4O5.js.map +0 -1
  60. package/dist/chunk-6FW5E54W.cjs.map +0 -1
  61. package/dist/chunk-HLM5BZZQ.js +0 -35
  62. package/dist/chunk-HLM5BZZQ.js.map +0 -1
  63. package/dist/chunk-QLPCVK7C.cjs +0 -38
  64. package/dist/chunk-QLPCVK7C.cjs.map +0 -1
@@ -348,6 +348,9 @@ var FormaJS = (() => {
348
348
  }
349
349
  }
350
350
  });
351
+ function getActiveSub() {
352
+ return activeSub;
353
+ }
351
354
  function setActiveSub(sub) {
352
355
  const prevSub = activeSub;
353
356
  activeSub = sub;
@@ -593,16 +596,47 @@ var FormaJS = (() => {
593
596
  }
594
597
  }
595
598
 
599
+ // src/reactive/dev.ts
600
+ function isDev() {
601
+ if (typeof process !== "undefined") {
602
+ return process.env?.NODE_ENV !== "production";
603
+ }
604
+ return typeof __FORMA_DEV__ !== "undefined" ? !!__FORMA_DEV__ : false;
605
+ }
606
+ var __DEV__ = isDev();
607
+ var _errorHandlers = /* @__PURE__ */ new Set();
608
+ function onError(handler) {
609
+ _errorHandlers.add(handler);
610
+ return () => {
611
+ _errorHandlers.delete(handler);
612
+ };
613
+ }
614
+ function reportError(error, source) {
615
+ for (const handler of _errorHandlers) {
616
+ try {
617
+ handler(error, source ? { source } : {});
618
+ } catch {
619
+ }
620
+ }
621
+ if (isDev()) {
622
+ console.error(`[forma] ${source ?? "Unknown"} error:`, error);
623
+ }
624
+ }
625
+
596
626
  // src/reactive/signal.ts
627
+ var signalNames = /* @__PURE__ */ new WeakMap();
597
628
  function applySignalSet(s, v, equals) {
598
629
  if (typeof v !== "function") {
599
- if (equals) {
600
- const prevSub2 = setActiveSub(void 0);
601
- const prev2 = s();
602
- setActiveSub(prevSub2);
603
- if (equals(prev2, v)) return;
630
+ if (!equals) {
631
+ s(v);
632
+ return;
604
633
  }
634
+ const prevSub2 = setActiveSub(void 0);
635
+ const prev2 = s();
636
+ setActiveSub(prevSub2);
637
+ if (equals(prev2, v)) return;
605
638
  s(v);
639
+ if (Object.is(prev2, v)) forceNotify(s);
606
640
  return;
607
641
  }
608
642
  const prevSub = setActiveSub(void 0);
@@ -611,10 +645,19 @@ var FormaJS = (() => {
611
645
  const next = v(prev);
612
646
  if (equals && equals(prev, next)) return;
613
647
  s(next);
648
+ if (equals && Object.is(prev, next)) forceNotify(s);
649
+ }
650
+ function forceNotify(s) {
651
+ trigger(() => {
652
+ s();
653
+ });
614
654
  }
615
655
  function createSignal(initialValue, options) {
616
656
  const s = signal(initialValue);
617
657
  const getter = s;
658
+ if (__DEV__ && options?.name) {
659
+ signalNames.set(getter, options.name);
660
+ }
618
661
  const eq = options?.equals;
619
662
  const setter = (v) => applySignalSet(s, v, eq);
620
663
  return [getter, setter];
@@ -623,29 +666,73 @@ var FormaJS = (() => {
623
666
  // src/reactive/root.ts
624
667
  var currentRoot = null;
625
668
  var rootStack = [];
669
+ var currentOwner = null;
670
+ function getOwner() {
671
+ return currentOwner;
672
+ }
673
+ function runWithOwner(owner, fn) {
674
+ const prev = currentOwner;
675
+ currentOwner = owner;
676
+ try {
677
+ return fn();
678
+ } finally {
679
+ currentOwner = prev;
680
+ }
681
+ }
682
+ function registerOwnerDisposer(owner, dispose) {
683
+ owner.disposers.push(dispose);
684
+ }
685
+ function createChildOwner() {
686
+ return { disposers: [] };
687
+ }
688
+ function disposeOwner(owner) {
689
+ const ds = owner.disposers;
690
+ for (const d of ds) {
691
+ try {
692
+ d();
693
+ } catch {
694
+ }
695
+ }
696
+ ds.length = 0;
697
+ }
626
698
  function createRootImpl(fn, owned) {
627
699
  const scope = { disposers: [], scopeDispose: null };
628
700
  const parentRoot = owned ? currentRoot : null;
629
701
  rootStack.push(currentRoot);
630
702
  currentRoot = scope;
703
+ const prevOwner = currentOwner;
704
+ currentOwner = scope;
631
705
  let disposed = false;
632
- const dispose = () => {
633
- if (disposed) return;
634
- disposed = true;
635
- if (scope.scopeDispose) {
706
+ let setupComplete = false;
707
+ let disposeRequestedDuringSetup = false;
708
+ const runDisposers = () => {
709
+ for (const d of scope.disposers) {
636
710
  try {
637
- scope.scopeDispose();
711
+ d();
638
712
  } catch {
639
713
  }
640
- scope.scopeDispose = null;
641
714
  }
642
- for (const d of scope.disposers) {
715
+ scope.disposers.length = 0;
716
+ };
717
+ const runTeardown = () => {
718
+ if (scope.scopeDispose) {
643
719
  try {
644
- d();
720
+ scope.scopeDispose();
645
721
  } catch {
646
722
  }
723
+ scope.scopeDispose = null;
647
724
  }
648
- scope.disposers.length = 0;
725
+ runDisposers();
726
+ };
727
+ const dispose = () => {
728
+ if (disposed) return;
729
+ disposed = true;
730
+ if (!setupComplete) {
731
+ disposeRequestedDuringSetup = true;
732
+ runDisposers();
733
+ return;
734
+ }
735
+ runTeardown();
649
736
  };
650
737
  if (parentRoot) {
651
738
  parentRoot.disposers.push(dispose);
@@ -666,8 +753,13 @@ var FormaJS = (() => {
666
753
  setActiveSub(prevSub);
667
754
  }
668
755
  }
756
+ setupComplete = true;
757
+ if (disposeRequestedDuringSetup) {
758
+ runTeardown();
759
+ }
669
760
  } finally {
670
761
  currentRoot = rootStack.pop() ?? null;
762
+ currentOwner = prevOwner;
671
763
  }
672
764
  return result;
673
765
  }
@@ -678,12 +770,12 @@ var FormaJS = (() => {
678
770
  return createRootImpl(fn, false);
679
771
  }
680
772
  function registerDisposer(dispose) {
681
- if (currentRoot) {
682
- currentRoot.disposers.push(dispose);
773
+ if (currentOwner) {
774
+ currentOwner.disposers.push(dispose);
683
775
  }
684
776
  }
685
777
  function hasActiveRoot() {
686
- return currentRoot !== null;
778
+ return currentOwner !== null;
687
779
  }
688
780
 
689
781
  // src/reactive/cleanup.ts
@@ -697,30 +789,13 @@ var FormaJS = (() => {
697
789
  return prev;
698
790
  }
699
791
 
700
- // src/reactive/dev.ts
701
- var __DEV__ = typeof process !== "undefined" ? process.env?.NODE_ENV !== "production" : true;
702
- var _errorHandler = null;
703
- function onError(handler) {
704
- _errorHandler = handler;
705
- }
706
- function reportError(error, source) {
707
- if (_errorHandler) {
708
- try {
709
- _errorHandler(error, source ? { source } : {});
710
- } catch {
711
- }
712
- }
713
- if (__DEV__) {
714
- console.error(`[forma] ${source ?? "Unknown"} error:`, error);
715
- }
716
- }
717
-
718
792
  // src/reactive/effect.ts
719
793
  var POOL_SIZE = 32;
720
794
  var MAX_REENTRANT_RUNS = 100;
721
795
  var pool = [];
722
796
  for (let i = 0; i < POOL_SIZE; i++) pool.push([]);
723
797
  var poolIdx = POOL_SIZE;
798
+ var PENDING = 32;
724
799
  function acquireArray() {
725
800
  if (poolIdx > 0) {
726
801
  const arr = pool[--poolIdx];
@@ -761,7 +836,8 @@ var FormaJS = (() => {
761
836
  return dispose;
762
837
  }
763
838
  function createEffect(fn) {
764
- const shouldRegister = hasActiveRoot();
839
+ const ownerAtCreate = getOwner();
840
+ const childOwner = createChildOwner();
765
841
  let cleanup2;
766
842
  let cleanupBag;
767
843
  let nextCleanup;
@@ -780,11 +856,8 @@ var FormaJS = (() => {
780
856
  }
781
857
  nextCleanup = cb;
782
858
  };
783
- let skipCleanupInfra = false;
784
- let firstRun = true;
785
- let running = false;
786
- let rerunRequested = false;
787
859
  const runOnce = () => {
860
+ disposeOwner(childOwner);
788
861
  if (cleanup2 !== void 0) {
789
862
  runCleanup(cleanup2);
790
863
  cleanup2 = void 0;
@@ -794,68 +867,46 @@ var FormaJS = (() => {
794
867
  releaseArray(cleanupBag);
795
868
  cleanupBag = void 0;
796
869
  }
797
- if (skipCleanupInfra) {
798
- try {
799
- fn();
800
- } catch (e) {
801
- reportError(e, "effect");
802
- }
803
- return;
804
- }
805
870
  nextCleanup = void 0;
806
871
  nextCleanupBag = void 0;
807
872
  const prevCollector = setCleanupCollector(addCleanup);
808
873
  try {
809
- const result = fn();
874
+ const result = runWithOwner(childOwner, fn);
810
875
  if (typeof result === "function") {
811
876
  addCleanup(result);
812
877
  }
813
- if (nextCleanup === void 0 && nextCleanupBag === void 0) {
814
- if (firstRun) skipCleanupInfra = true;
815
- return;
816
- }
817
878
  if (nextCleanupBag !== void 0) {
818
879
  cleanupBag = nextCleanupBag;
819
- } else {
880
+ } else if (nextCleanup !== void 0) {
820
881
  cleanup2 = nextCleanup;
821
882
  }
822
883
  } catch (e) {
823
884
  reportError(e, "effect");
824
885
  if (nextCleanupBag !== void 0) {
825
886
  cleanupBag = nextCleanupBag;
826
- } else {
887
+ } else if (nextCleanup !== void 0) {
827
888
  cleanup2 = nextCleanup;
828
889
  }
829
890
  } finally {
830
891
  setCleanupCollector(prevCollector);
831
- firstRun = false;
832
892
  }
833
893
  };
834
894
  const safeFn = () => {
835
- if (running) {
836
- rerunRequested = true;
837
- return;
838
- }
839
- running = true;
840
- try {
841
- let reentrantRuns = 0;
842
- do {
843
- rerunRequested = false;
844
- runOnce();
845
- if (rerunRequested) {
846
- reentrantRuns++;
847
- if (reentrantRuns >= MAX_REENTRANT_RUNS) {
848
- reportError(
849
- new Error(`createEffect exceeded ${MAX_REENTRANT_RUNS} re-entrant runs`),
850
- "effect"
851
- );
852
- rerunRequested = false;
853
- }
854
- }
855
- } while (rerunRequested);
856
- } finally {
857
- running = false;
858
- }
895
+ const node = getActiveSub();
896
+ let reentrantRuns = 0;
897
+ do {
898
+ if (node) node.flags &= ~PENDING;
899
+ runOnce();
900
+ if (node === void 0 || (node.flags & PENDING) === 0) break;
901
+ if (++reentrantRuns >= MAX_REENTRANT_RUNS) {
902
+ node.flags &= ~PENDING;
903
+ reportError(
904
+ new Error(`createEffect exceeded ${MAX_REENTRANT_RUNS} self-triggered re-runs (cycle?)`),
905
+ "effect"
906
+ );
907
+ break;
908
+ }
909
+ } while (true);
859
910
  };
860
911
  const dispose = effect(safeFn);
861
912
  let disposed = false;
@@ -863,6 +914,7 @@ var FormaJS = (() => {
863
914
  if (disposed) return;
864
915
  disposed = true;
865
916
  dispose();
917
+ disposeOwner(childOwner);
866
918
  if (cleanup2 !== void 0) {
867
919
  runCleanup(cleanup2);
868
920
  cleanup2 = void 0;
@@ -873,15 +925,42 @@ var FormaJS = (() => {
873
925
  cleanupBag = void 0;
874
926
  }
875
927
  };
876
- if (shouldRegister) {
877
- registerDisposer(wrappedDispose);
928
+ if (ownerAtCreate) {
929
+ registerOwnerDisposer(ownerAtCreate, wrappedDispose);
878
930
  }
879
931
  return wrappedDispose;
880
932
  }
881
933
 
882
934
  // src/reactive/computed.ts
935
+ var ERR = /* @__PURE__ */ Symbol("formaComputedError");
936
+ function isErrBox(v) {
937
+ return typeof v === "object" && v !== null && ERR in v;
938
+ }
883
939
  function createComputed(fn) {
884
- return computed(fn);
940
+ let errored = false;
941
+ let error;
942
+ let lastGood;
943
+ const raw = computed(() => {
944
+ try {
945
+ const v = fn(lastGood);
946
+ errored = false;
947
+ error = void 0;
948
+ lastGood = v;
949
+ return v;
950
+ } catch (e) {
951
+ errored = true;
952
+ error = e;
953
+ reportError(e, "computed");
954
+ return { [ERR]: e };
955
+ }
956
+ });
957
+ const reader = () => {
958
+ const v = raw();
959
+ if (errored || isErrBox(v)) throw error;
960
+ return v;
961
+ };
962
+ Object.defineProperty(reader, "name", { value: raw.name, configurable: true });
963
+ return reader;
885
964
  }
886
965
 
887
966
  // src/reactive/memo.ts
@@ -974,25 +1053,34 @@ var FormaJS = (() => {
974
1053
  suspenseCtx.increment();
975
1054
  suspensePending = true;
976
1055
  }
977
- setLoading(true);
978
- setError(void 0);
979
- Promise.resolve(fetcher(sourceValue)).then((result) => {
1056
+ batch(() => {
1057
+ setLoading(true);
1058
+ setError(void 0);
1059
+ });
1060
+ let promise;
1061
+ try {
1062
+ promise = Promise.resolve(fetcher(sourceValue, { signal: controller.signal }));
1063
+ } catch (err) {
1064
+ promise = Promise.reject(err);
1065
+ }
1066
+ promise.then((result) => {
980
1067
  if (isLatest() && !controller.signal.aborted) {
981
- setData(() => result);
1068
+ batch(() => {
1069
+ setData(() => result);
1070
+ setLoading(false);
1071
+ });
982
1072
  }
983
1073
  }).catch((err) => {
984
- if (isLatest() && !controller.signal.aborted) {
985
- if (err?.name !== "AbortError") {
1074
+ if (isLatest() && !controller.signal.aborted && err?.name !== "AbortError") {
1075
+ batch(() => {
986
1076
  setError(err);
987
- }
1077
+ setLoading(false);
1078
+ });
988
1079
  }
989
1080
  }).finally(() => {
990
1081
  if (suspensePending) suspenseCtx?.decrement();
991
- if (isLatest()) {
992
- setLoading(false);
993
- if (abortController === controller) {
994
- abortController = null;
995
- }
1082
+ if (isLatest() && abortController === controller) {
1083
+ abortController = null;
996
1084
  }
997
1085
  });
998
1086
  };
@@ -1000,6 +1088,15 @@ var FormaJS = (() => {
1000
1088
  source();
1001
1089
  doFetch();
1002
1090
  });
1091
+ if (hasActiveRoot()) {
1092
+ registerDisposer(() => {
1093
+ fetchVersion++;
1094
+ if (abortController) {
1095
+ abortController.abort();
1096
+ abortController = null;
1097
+ }
1098
+ });
1099
+ }
1003
1100
  const resource = (() => data());
1004
1101
  resource.loading = loading;
1005
1102
  resource.error = error;