@flexsurfer/reflex 0.1.18 → 0.1.20

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.cjs CHANGED
@@ -162,6 +162,7 @@ function clearSubs() {
162
162
  clearReactions();
163
163
  clearHandlers("sub");
164
164
  clearHandlers("subDeps");
165
+ clearSubConfigs();
165
166
  }
166
167
  var interceptorsRegistry = /* @__PURE__ */ new Map();
167
168
  function getInterceptors(eventId) {
@@ -170,6 +171,20 @@ function getInterceptors(eventId) {
170
171
  function setInterceptors(eventId, interceptors) {
171
172
  interceptorsRegistry.set(eventId, interceptors);
172
173
  }
174
+ var subConfigRegistry = /* @__PURE__ */ new Map();
175
+ function getSubConfig(subId) {
176
+ return subConfigRegistry.get(subId);
177
+ }
178
+ function setSubConfig(subId, config) {
179
+ subConfigRegistry.set(subId, config);
180
+ }
181
+ function clearSubConfigs(subId) {
182
+ if (subId == null) {
183
+ subConfigRegistry.clear();
184
+ } else {
185
+ subConfigRegistry.delete(subId);
186
+ }
187
+ }
173
188
 
174
189
  // src/schedule.ts
175
190
  function scheduleAfterRender(f) {
@@ -584,8 +599,10 @@ regEffect(DISPATCH, (value) => {
584
599
  var import_immer2 = require("immer");
585
600
 
586
601
  // src/settings.ts
602
+ var import_fast_deep_equal = __toESM(require("fast-deep-equal"), 1);
587
603
  var store = {
588
- globalInterceptors: []
604
+ globalInterceptors: [],
605
+ globalEqualityCheck: import_fast_deep_equal.default
589
606
  };
590
607
  function replaceGlobalInterceptor(globalInterceptors, interceptor) {
591
608
  return globalInterceptors.reduce((ret, existingInterceptor) => {
@@ -615,6 +632,9 @@ function clearGlobalInterceptors(id) {
615
632
  store.globalInterceptors = store.globalInterceptors.filter((interceptor) => interceptor.id !== id);
616
633
  }
617
634
  }
635
+ function getGlobalEqualityCheck() {
636
+ return store.globalEqualityCheck;
637
+ }
618
638
 
619
639
  // src/trace.ts
620
640
  var nextId = 1;
@@ -850,7 +870,7 @@ function defaultErrorHandler(originalError, reflexError) {
850
870
  regEventErrorHandler(defaultErrorHandler);
851
871
 
852
872
  // src/reaction.ts
853
- var import_fast_deep_equal = __toESM(require("fast-deep-equal"), 1);
873
+ var import_fast_deep_equal2 = __toESM(require("fast-deep-equal"), 1);
854
874
  var Reaction = class _Reaction {
855
875
  id = "";
856
876
  computeFn;
@@ -863,12 +883,14 @@ var Reaction = class _Reaction {
863
883
  version = 0;
864
884
  depsVersions = [];
865
885
  subVector;
866
- constructor(computeFn, deps) {
886
+ equalityCheck;
887
+ constructor(computeFn, deps, equalityCheck) {
867
888
  this.computeFn = computeFn;
868
889
  this.deps = deps;
890
+ this.equalityCheck = equalityCheck || import_fast_deep_equal2.default;
869
891
  }
870
- static create(fn, deps) {
871
- return new _Reaction(fn, deps);
892
+ static create(fn, deps, equalityCheck) {
893
+ return new _Reaction(fn, deps, equalityCheck);
872
894
  }
873
895
  computeValue() {
874
896
  this.ensureDirty();
@@ -925,7 +947,7 @@ var Reaction = class _Reaction {
925
947
  try {
926
948
  let changed = false;
927
949
  withTrace(
928
- { operation: this.subVector?.[0] ?? "", opType: "sub/run", tags: { queryV: this.subVector, reaction: this.id } },
950
+ { operation: this.subVector?.[0] ?? "", opType: "sub/run", tags: { queryV: this.subVector, reaction: this.id, deps: this.deps?.map((d) => d.getId()) ?? [] } },
929
951
  () => {
930
952
  if (this.isRoot) {
931
953
  changed = true;
@@ -934,10 +956,10 @@ var Reaction = class _Reaction {
934
956
  const depValues = this.deps?.map((d) => d.getDepValue(notifyWatchers)) ?? [];
935
957
  const values = depValues.map(([value]) => value);
936
958
  const currentVersions = depValues.map(([, version]) => version);
937
- const versionsChanged = !(0, import_fast_deep_equal.default)(currentVersions, this.depsVersions);
959
+ const versionsChanged = !(0, import_fast_deep_equal2.default)(currentVersions, this.depsVersions);
938
960
  if (this.value === void 0 || versionsChanged) {
939
961
  let newVal = this.computeFn(...values);
940
- changed = !(0, import_fast_deep_equal.default)(newVal, this.value);
962
+ changed = !this.equalityCheck(newVal, this.value);
941
963
  if (changed) {
942
964
  this.value = newVal;
943
965
  }
@@ -957,7 +979,8 @@ var Reaction = class _Reaction {
957
979
  withTrace(
958
980
  {
959
981
  opType: "render",
960
- operation: w.componentName
982
+ operation: w.componentName,
983
+ tags: { reaction: this.id }
961
984
  },
962
985
  () => {
963
986
  w.callback(this.value);
@@ -1050,13 +1073,16 @@ var Reaction = class _Reaction {
1050
1073
  // src/subs.ts
1051
1074
  var KIND4 = "sub";
1052
1075
  var KIND_DEPS = "subDeps";
1053
- function regSub(id, computeFn, depsFn) {
1076
+ function regSub(id, computeFn, depsFn, config) {
1054
1077
  if (hasHandler(KIND4, id)) {
1055
1078
  consoleLog("warn", `[reflex] Overriding. Subscription '${id}' already registered.`);
1056
1079
  }
1057
1080
  if (!computeFn) {
1058
1081
  registerHandler(KIND4, id, () => getAppDb()[id]);
1059
1082
  registerHandler(KIND_DEPS, id, () => []);
1083
+ } else if (typeof computeFn === "string") {
1084
+ registerHandler(KIND4, id, () => getAppDb()[computeFn]);
1085
+ registerHandler(KIND_DEPS, id, () => []);
1060
1086
  } else {
1061
1087
  if (!depsFn) {
1062
1088
  consoleLog("error", `[reflex] Subscription '${id}' has computeFn but missing depsFn. Computed subscriptions must specify their dependencies.`);
@@ -1065,6 +1091,9 @@ function regSub(id, computeFn, depsFn) {
1065
1091
  registerHandler(KIND4, id, computeFn);
1066
1092
  registerHandler(KIND_DEPS, id, depsFn);
1067
1093
  }
1094
+ if (config) {
1095
+ setSubConfig(id, config);
1096
+ }
1068
1097
  }
1069
1098
  function getOrCreateReaction(subVector) {
1070
1099
  const subId = subVector[0];
@@ -1087,6 +1116,8 @@ function getOrCreateReaction(subVector) {
1087
1116
  const depsReactions = depsVectors.map((depVector) => {
1088
1117
  return getOrCreateReaction(depVector);
1089
1118
  });
1119
+ const subConfig = getSubConfig(subId);
1120
+ const equalityCheck = subConfig?.equalityCheck || getGlobalEqualityCheck();
1090
1121
  const reaction = Reaction.create(
1091
1122
  (...depValues) => {
1092
1123
  if (params.length > 0) {
@@ -1095,7 +1126,8 @@ function getOrCreateReaction(subVector) {
1095
1126
  return computeFn(...depValues);
1096
1127
  }
1097
1128
  },
1098
- depsReactions
1129
+ depsReactions,
1130
+ equalityCheck
1099
1131
  );
1100
1132
  reaction.setId(subVectorKey);
1101
1133
  reaction.setSubVector(subVector);
package/dist/index.d.cts CHANGED
@@ -13,6 +13,9 @@ type ErrorHandler = (originalError: Error, reflexError: Error & {
13
13
  type SubVector = [Id, ...any[]];
14
14
  type SubHandler = (...values: any[]) => any;
15
15
  type SubDepsHandler = (...params: any[]) => SubVector[];
16
+ interface SubConfig {
17
+ equalityCheck?: EqualityCheckFn;
18
+ }
16
19
  type Effects = [string, any?][];
17
20
  interface DispatchLaterEffect {
18
21
  ms: number;
@@ -38,6 +41,7 @@ interface Interceptor<T = Record<string, any>> {
38
41
  after?: (context: Context<T>) => Context<T>;
39
42
  comment?: string;
40
43
  }
44
+ type EqualityCheckFn = (a: any, b: any) => boolean;
41
45
 
42
46
  declare function initAppDb<T = Record<string, any>>(value: Db<T>): void;
43
47
  declare function getAppDb<T = Record<string, any>>(): Db<T>;
@@ -110,8 +114,9 @@ declare class Reaction<T> {
110
114
  private version;
111
115
  private depsVersions;
112
116
  private subVector;
113
- constructor(computeFn: (...depValues: any[]) => T, deps?: Reaction<any>[]);
114
- static create<R>(fn: (...values: any[]) => R, deps?: Reaction<any>[]): Reaction<R>;
117
+ private equalityCheck;
118
+ constructor(computeFn: (...depValues: any[]) => T, deps?: Reaction<any>[], equalityCheck?: EqualityCheckFn);
119
+ static create<R>(fn: (...values: any[]) => R, deps?: Reaction<any>[], equalityCheck?: EqualityCheckFn): Reaction<R>;
115
120
  computeValue(): T;
116
121
  getValue(): T;
117
122
  getDepValue(notifyWatchers?: boolean): [T, number];
@@ -135,7 +140,7 @@ declare class Reaction<T> {
135
140
  get isRoot(): boolean;
136
141
  }
137
142
 
138
- declare function regSub<R>(id: Id, computeFn?: (...values: any[]) => R, depsFn?: (...params: any[]) => SubVector[]): void;
143
+ declare function regSub<R>(id: Id, computeFn?: ((...values: any[]) => R) | string, depsFn?: (...params: any[]) => SubVector[], config?: SubConfig): void;
139
144
  declare function getSubscriptionValue<T>(subVector: SubVector): T;
140
145
 
141
146
  declare function regEffect(id: string, handler: EffectHandler): void;
package/dist/index.d.ts CHANGED
@@ -13,6 +13,9 @@ type ErrorHandler = (originalError: Error, reflexError: Error & {
13
13
  type SubVector = [Id, ...any[]];
14
14
  type SubHandler = (...values: any[]) => any;
15
15
  type SubDepsHandler = (...params: any[]) => SubVector[];
16
+ interface SubConfig {
17
+ equalityCheck?: EqualityCheckFn;
18
+ }
16
19
  type Effects = [string, any?][];
17
20
  interface DispatchLaterEffect {
18
21
  ms: number;
@@ -38,6 +41,7 @@ interface Interceptor<T = Record<string, any>> {
38
41
  after?: (context: Context<T>) => Context<T>;
39
42
  comment?: string;
40
43
  }
44
+ type EqualityCheckFn = (a: any, b: any) => boolean;
41
45
 
42
46
  declare function initAppDb<T = Record<string, any>>(value: Db<T>): void;
43
47
  declare function getAppDb<T = Record<string, any>>(): Db<T>;
@@ -110,8 +114,9 @@ declare class Reaction<T> {
110
114
  private version;
111
115
  private depsVersions;
112
116
  private subVector;
113
- constructor(computeFn: (...depValues: any[]) => T, deps?: Reaction<any>[]);
114
- static create<R>(fn: (...values: any[]) => R, deps?: Reaction<any>[]): Reaction<R>;
117
+ private equalityCheck;
118
+ constructor(computeFn: (...depValues: any[]) => T, deps?: Reaction<any>[], equalityCheck?: EqualityCheckFn);
119
+ static create<R>(fn: (...values: any[]) => R, deps?: Reaction<any>[], equalityCheck?: EqualityCheckFn): Reaction<R>;
115
120
  computeValue(): T;
116
121
  getValue(): T;
117
122
  getDepValue(notifyWatchers?: boolean): [T, number];
@@ -135,7 +140,7 @@ declare class Reaction<T> {
135
140
  get isRoot(): boolean;
136
141
  }
137
142
 
138
- declare function regSub<R>(id: Id, computeFn?: (...values: any[]) => R, depsFn?: (...params: any[]) => SubVector[]): void;
143
+ declare function regSub<R>(id: Id, computeFn?: ((...values: any[]) => R) | string, depsFn?: (...params: any[]) => SubVector[], config?: SubConfig): void;
139
144
  declare function getSubscriptionValue<T>(subVector: SubVector): T;
140
145
 
141
146
  declare function regEffect(id: string, handler: EffectHandler): void;
package/dist/index.mjs CHANGED
@@ -87,6 +87,7 @@ function clearSubs() {
87
87
  clearReactions();
88
88
  clearHandlers("sub");
89
89
  clearHandlers("subDeps");
90
+ clearSubConfigs();
90
91
  }
91
92
  var interceptorsRegistry = /* @__PURE__ */ new Map();
92
93
  function getInterceptors(eventId) {
@@ -95,6 +96,20 @@ function getInterceptors(eventId) {
95
96
  function setInterceptors(eventId, interceptors) {
96
97
  interceptorsRegistry.set(eventId, interceptors);
97
98
  }
99
+ var subConfigRegistry = /* @__PURE__ */ new Map();
100
+ function getSubConfig(subId) {
101
+ return subConfigRegistry.get(subId);
102
+ }
103
+ function setSubConfig(subId, config) {
104
+ subConfigRegistry.set(subId, config);
105
+ }
106
+ function clearSubConfigs(subId) {
107
+ if (subId == null) {
108
+ subConfigRegistry.clear();
109
+ } else {
110
+ subConfigRegistry.delete(subId);
111
+ }
112
+ }
98
113
 
99
114
  // src/schedule.ts
100
115
  function scheduleAfterRender(f) {
@@ -509,8 +524,10 @@ regEffect(DISPATCH, (value) => {
509
524
  import { enablePatches, produceWithPatches } from "immer";
510
525
 
511
526
  // src/settings.ts
527
+ import isEqual from "fast-deep-equal";
512
528
  var store = {
513
- globalInterceptors: []
529
+ globalInterceptors: [],
530
+ globalEqualityCheck: isEqual
514
531
  };
515
532
  function replaceGlobalInterceptor(globalInterceptors, interceptor) {
516
533
  return globalInterceptors.reduce((ret, existingInterceptor) => {
@@ -540,6 +557,9 @@ function clearGlobalInterceptors(id) {
540
557
  store.globalInterceptors = store.globalInterceptors.filter((interceptor) => interceptor.id !== id);
541
558
  }
542
559
  }
560
+ function getGlobalEqualityCheck() {
561
+ return store.globalEqualityCheck;
562
+ }
543
563
 
544
564
  // src/trace.ts
545
565
  var nextId = 1;
@@ -775,7 +795,7 @@ function defaultErrorHandler(originalError, reflexError) {
775
795
  regEventErrorHandler(defaultErrorHandler);
776
796
 
777
797
  // src/reaction.ts
778
- import isEqual from "fast-deep-equal";
798
+ import isEqual2 from "fast-deep-equal";
779
799
  var Reaction = class _Reaction {
780
800
  id = "";
781
801
  computeFn;
@@ -788,12 +808,14 @@ var Reaction = class _Reaction {
788
808
  version = 0;
789
809
  depsVersions = [];
790
810
  subVector;
791
- constructor(computeFn, deps) {
811
+ equalityCheck;
812
+ constructor(computeFn, deps, equalityCheck) {
792
813
  this.computeFn = computeFn;
793
814
  this.deps = deps;
815
+ this.equalityCheck = equalityCheck || isEqual2;
794
816
  }
795
- static create(fn, deps) {
796
- return new _Reaction(fn, deps);
817
+ static create(fn, deps, equalityCheck) {
818
+ return new _Reaction(fn, deps, equalityCheck);
797
819
  }
798
820
  computeValue() {
799
821
  this.ensureDirty();
@@ -850,7 +872,7 @@ var Reaction = class _Reaction {
850
872
  try {
851
873
  let changed = false;
852
874
  withTrace(
853
- { operation: this.subVector?.[0] ?? "", opType: "sub/run", tags: { queryV: this.subVector, reaction: this.id } },
875
+ { operation: this.subVector?.[0] ?? "", opType: "sub/run", tags: { queryV: this.subVector, reaction: this.id, deps: this.deps?.map((d) => d.getId()) ?? [] } },
854
876
  () => {
855
877
  if (this.isRoot) {
856
878
  changed = true;
@@ -859,10 +881,10 @@ var Reaction = class _Reaction {
859
881
  const depValues = this.deps?.map((d) => d.getDepValue(notifyWatchers)) ?? [];
860
882
  const values = depValues.map(([value]) => value);
861
883
  const currentVersions = depValues.map(([, version]) => version);
862
- const versionsChanged = !isEqual(currentVersions, this.depsVersions);
884
+ const versionsChanged = !isEqual2(currentVersions, this.depsVersions);
863
885
  if (this.value === void 0 || versionsChanged) {
864
886
  let newVal = this.computeFn(...values);
865
- changed = !isEqual(newVal, this.value);
887
+ changed = !this.equalityCheck(newVal, this.value);
866
888
  if (changed) {
867
889
  this.value = newVal;
868
890
  }
@@ -882,7 +904,8 @@ var Reaction = class _Reaction {
882
904
  withTrace(
883
905
  {
884
906
  opType: "render",
885
- operation: w.componentName
907
+ operation: w.componentName,
908
+ tags: { reaction: this.id }
886
909
  },
887
910
  () => {
888
911
  w.callback(this.value);
@@ -975,13 +998,16 @@ var Reaction = class _Reaction {
975
998
  // src/subs.ts
976
999
  var KIND4 = "sub";
977
1000
  var KIND_DEPS = "subDeps";
978
- function regSub(id, computeFn, depsFn) {
1001
+ function regSub(id, computeFn, depsFn, config) {
979
1002
  if (hasHandler(KIND4, id)) {
980
1003
  consoleLog("warn", `[reflex] Overriding. Subscription '${id}' already registered.`);
981
1004
  }
982
1005
  if (!computeFn) {
983
1006
  registerHandler(KIND4, id, () => getAppDb()[id]);
984
1007
  registerHandler(KIND_DEPS, id, () => []);
1008
+ } else if (typeof computeFn === "string") {
1009
+ registerHandler(KIND4, id, () => getAppDb()[computeFn]);
1010
+ registerHandler(KIND_DEPS, id, () => []);
985
1011
  } else {
986
1012
  if (!depsFn) {
987
1013
  consoleLog("error", `[reflex] Subscription '${id}' has computeFn but missing depsFn. Computed subscriptions must specify their dependencies.`);
@@ -990,6 +1016,9 @@ function regSub(id, computeFn, depsFn) {
990
1016
  registerHandler(KIND4, id, computeFn);
991
1017
  registerHandler(KIND_DEPS, id, depsFn);
992
1018
  }
1019
+ if (config) {
1020
+ setSubConfig(id, config);
1021
+ }
993
1022
  }
994
1023
  function getOrCreateReaction(subVector) {
995
1024
  const subId = subVector[0];
@@ -1012,6 +1041,8 @@ function getOrCreateReaction(subVector) {
1012
1041
  const depsReactions = depsVectors.map((depVector) => {
1013
1042
  return getOrCreateReaction(depVector);
1014
1043
  });
1044
+ const subConfig = getSubConfig(subId);
1045
+ const equalityCheck = subConfig?.equalityCheck || getGlobalEqualityCheck();
1015
1046
  const reaction = Reaction.create(
1016
1047
  (...depValues) => {
1017
1048
  if (params.length > 0) {
@@ -1020,7 +1051,8 @@ function getOrCreateReaction(subVector) {
1020
1051
  return computeFn(...depValues);
1021
1052
  }
1022
1053
  },
1023
- depsReactions
1054
+ depsReactions,
1055
+ equalityCheck
1024
1056
  );
1025
1057
  reaction.setId(subVectorKey);
1026
1058
  reaction.setSubVector(subVector);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flexsurfer/reflex",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",