@flexsurfer/reflex 0.1.11 โ†’ 0.1.13

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 CHANGED
@@ -1,5 +1,5 @@
1
1
  <div align="center">
2
- <img src="reflex-logo-300kb.png" alt="Reflex Logo" width="200" />
2
+ <img src="reflex_logo.jpg" alt="Reflex Logo" width="200" />
3
3
  </div>
4
4
 
5
5
  **re-frame for the JavaScript world**
@@ -20,6 +20,8 @@ After many years of building applications with re-frame in the ClojureScript wor
20
20
  ๐Ÿงฉ **Composable Architecture** - Build complex apps from simple, reusable pieces
21
21
  ๐Ÿ”„ **Reactive Subscriptions** - UI automatically updates when state changes
22
22
  ๐ŸŒ **Multi-Platform Support** - With effects separation, it's super easy to support multiple platforms with the same codebase, including web, mobile, and desktop
23
+ ๐Ÿค– **AI Friendly** - Reviewing AI-generated changes is easier because all logic is expressed through pure, isolated functions, making each change understandable, verifiable, and deterministic.
24
+ ๐Ÿ› ๏ธ **Integrated DevTools** - [`@flexsurfer/reflex-devtools`](https://github.com/flexsurfer/reflex-devtools) provides deep visibility into your appโ€™s state, events, and subscriptions in real time, forming a powerful combo with Reflex for effective development and debugging.
23
25
  โšก **Interceptor Pattern** - Powerful middleware system for cross-cutting concerns
24
26
  ๐Ÿ›ก๏ธ **Type Safety** - Full TypeScript support with excellent IDE experience
25
27
  ๐Ÿงช **Testability** - Pure functions make testing straightforward and reliable
@@ -28,6 +30,9 @@ After many years of building applications with re-frame in the ClojureScript wor
28
30
 
29
31
  ```bash
30
32
  npm install @flexsurfer/reflex
33
+ npm install --save-dev @flexsurfer/reflex-devtools
34
+
35
+ npx reflex-devtools
31
36
  ```
32
37
 
33
38
  ### Basic Example
@@ -38,8 +43,13 @@ import {
38
43
  regEvent,
39
44
  regSub,
40
45
  dispatch,
41
- useSubscription
46
+ useSubscription,
47
+ enableTracing
42
48
  } from '@flexsurfer/reflex';
49
+ import { enableDevtools } from '@flexsurfer/reflex-devtools'
50
+
51
+ enableTracing()
52
+ enableDevtools();
43
53
 
44
54
  // Initialize your app database
45
55
  initAppDb({ counter: 0 });
package/dist/index.cjs CHANGED
@@ -30,7 +30,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
+ DISPATCH: () => DISPATCH,
34
+ DISPATCH_LATER: () => DISPATCH_LATER,
33
35
  HotReloadWrapper: () => HotReloadWrapper,
36
+ NOW: () => NOW,
37
+ RANDOM: () => RANDOM,
34
38
  clearGlobalInterceptors: () => clearGlobalInterceptors,
35
39
  clearHandlers: () => clearHandlers,
36
40
  clearHotReloadCallbacks: () => clearHotReloadCallbacks,
@@ -314,8 +318,8 @@ function execute(eventV, interceptors) {
314
318
  try {
315
319
  return executeInterceptors(ctx);
316
320
  } catch (e) {
317
- const reFrameError = mergeExData(e, { eventV });
318
- errorHandler(e.cause || e, reFrameError);
321
+ const reflexError = mergeExData(e, { eventV });
322
+ errorHandler(e.cause || e, reflexError);
319
323
  return ctx;
320
324
  }
321
325
  }
@@ -343,11 +347,13 @@ function getInjectCofxInterceptor(id, value) {
343
347
  }
344
348
  };
345
349
  }
346
- regCoeffect("now", (coeffects) => ({
350
+ var NOW = "now";
351
+ var RANDOM = "random";
352
+ regCoeffect(NOW, (coeffects) => ({
347
353
  ...coeffects,
348
354
  now: Date.now()
349
355
  }));
350
- regCoeffect("random", (coeffects) => ({
356
+ regCoeffect(RANDOM, (coeffects) => ({
351
357
  ...coeffects,
352
358
  random: Math.random()
353
359
  }));
@@ -532,6 +538,8 @@ var doFxInterceptor = {
532
538
  return context;
533
539
  }
534
540
  };
541
+ var DISPATCH_LATER = "dispatch-later";
542
+ var DISPATCH = "dispatch";
535
543
  function dispatchLater(effect) {
536
544
  const { ms, dispatch: eventToDispatch } = effect;
537
545
  if (!Array.isArray(eventToDispatch) || typeof ms !== "number") {
@@ -543,10 +551,10 @@ function dispatchLater(effect) {
543
551
  }
544
552
  setTimeout(() => dispatch(eventToDispatch), Math.max(0, ms));
545
553
  }
546
- regEffect("dispatch-later", (value) => {
554
+ regEffect(DISPATCH_LATER, (value) => {
547
555
  dispatchLater(value);
548
556
  });
549
- regEffect("dispatch", (value) => {
557
+ regEffect(DISPATCH, (value) => {
550
558
  if (!Array.isArray(value)) {
551
559
  consoleLog("error", "[reflex] ignoring bad dispatch value. Expected a vector, but got:", value);
552
560
  return;
@@ -627,9 +635,7 @@ function resetTracing() {
627
635
  }
628
636
  function registerTraceCb(key, cb) {
629
637
  if (!traceEnabled) {
630
- console.warn(
631
- "Tracing is not enabled; call enableTracing() before registering callbacks"
632
- );
638
+ consoleLog("warn", "[reflex] [trace] Tracing is not enabled; call enableTracing() before registering callbacks");
633
639
  return;
634
640
  }
635
641
  traceCbs.set(key, cb);
@@ -645,7 +651,7 @@ function scheduleFlush() {
645
651
  try {
646
652
  cb(batch);
647
653
  } catch (e) {
648
- console.error("Error in trace callback", e);
654
+ consoleLog("warn", "Error in trace callback", e);
649
655
  }
650
656
  }
651
657
  }, DEBOUNCE_TIME);
@@ -810,11 +816,11 @@ function handle(eventV) {
810
816
  function regEventErrorHandler(handler) {
811
817
  registerHandler("error", "event-handler", handler);
812
818
  }
813
- function defaultErrorHandler(originalError, reFrameError) {
819
+ function defaultErrorHandler(originalError, reflexError) {
814
820
  consoleLog("error", "[reflex] Interceptor Exception:", {
815
821
  originalError,
816
- reFrameError,
817
- data: reFrameError.data
822
+ reflexError,
823
+ data: reflexError.data
818
824
  });
819
825
  throw originalError;
820
826
  }
@@ -971,7 +977,7 @@ var Reaction = class _Reaction {
971
977
  operation: this.subVector?.[0] ?? "",
972
978
  opType: "sub/dispose",
973
979
  tags: {
974
- subVector: this.subVector,
980
+ queryV: this.subVector,
975
981
  reaction: this.id
976
982
  }
977
983
  },
@@ -1198,7 +1204,11 @@ function HotReloadWrapper({ children }) {
1198
1204
  }
1199
1205
  // Annotate the CommonJS export names for ESM import in node:
1200
1206
  0 && (module.exports = {
1207
+ DISPATCH,
1208
+ DISPATCH_LATER,
1201
1209
  HotReloadWrapper,
1210
+ NOW,
1211
+ RANDOM,
1202
1212
  clearGlobalInterceptors,
1203
1213
  clearHandlers,
1204
1214
  clearHotReloadCallbacks,
package/dist/index.d.cts CHANGED
@@ -7,7 +7,7 @@ type EventVector = [Id, ...any[]];
7
7
  type EventHandler<T = Record<string, any>> = (coeffects: CoEffects<T>, ...params: any[]) => Effects | void;
8
8
  type EffectHandler = (value: any) => void;
9
9
  type CoEffectHandler<T = Record<string, any>> = (coeffects: CoEffects<T>, value?: any) => CoEffects<T>;
10
- type ErrorHandler = (originalError: Error, reFrameError: Error & {
10
+ type ErrorHandler = (originalError: Error, reflexError: Error & {
11
11
  data: any;
12
12
  }) => void;
13
13
  type SubVector = [Id, ...any[]];
@@ -57,16 +57,16 @@ declare function regEvent<T = Record<string, any>>(id: Id, handler: EventHandler
57
57
  * Only one handler can be registered. Registering a new handler clears the existing handler.
58
58
  *
59
59
  * This handler function has the signature:
60
- * `(originalError: Error, reFrameError: Error & { data: any }) => void`
60
+ * `(originalError: Error, reflexError: Error & { data: any }) => void`
61
61
  *
62
62
  * - `originalError`: A platform-native Error object.
63
63
  * Represents the original error thrown by user code.
64
64
  * This is the error you see when no handler is registered.
65
65
  *
66
- * - `reFrameError`: An Error object with additional data.
66
+ * - `reflexError`: An Error object with additional data.
67
67
  * Includes the stacktrace of reflex's internal functions,
68
68
  * and extra data about the interceptor process.
69
- * Access `reFrameError.data` to get this info.
69
+ * Access `reflexError.data` to get this info.
70
70
  *
71
71
  * The data includes:
72
72
  * - `interceptor`: the `id` of the throwing interceptor.
@@ -77,7 +77,7 @@ declare function regEventErrorHandler(handler: ErrorHandler): void;
77
77
  /**
78
78
  * Default error handler that logs errors to console
79
79
  */
80
- declare function defaultErrorHandler(originalError: Error, reFrameError: Error & {
80
+ declare function defaultErrorHandler(originalError: Error, reflexError: Error & {
81
81
  data: any;
82
82
  }): void;
83
83
 
@@ -85,8 +85,12 @@ declare function regSub<R>(id: Id, computeFn?: (...values: any[]) => R, depsFn?:
85
85
  declare function getSubscriptionValue<T>(subVector: SubVector): T;
86
86
 
87
87
  declare function regEffect(id: string, handler: EffectHandler): void;
88
+ declare const DISPATCH_LATER = "dispatch-later";
89
+ declare const DISPATCH = "dispatch";
88
90
 
89
91
  declare function regCoeffect(id: string, handler: CoEffectHandler): void;
92
+ declare const NOW = "now";
93
+ declare const RANDOM = "random";
90
94
 
91
95
  /**
92
96
  * Register a global interceptor
@@ -202,4 +206,4 @@ declare function disableTracing(): void;
202
206
  declare function registerTraceCb(key: string, cb: TraceCallback): void;
203
207
  declare function enableTracePrint(): void;
204
208
 
205
- export { CoEffectHandler, CoEffects, Context, Db, DispatchLaterEffect, EffectHandler, Effects, ErrorHandler, EventHandler, EventVector, HotReloadWrapper, Id, Interceptor, SubVector, clearGlobalInterceptors, clearHandlers, clearHotReloadCallbacks, clearReactions, clearSubs, debounceAndDispatch, defaultErrorHandler, disableTracing, dispatch, enableTracePrint, enableTracing, getAppDb, getGlobalInterceptors, getHandler, getSubscriptionValue, initAppDb, isDebugEnabled, regCoeffect, regEffect, regEvent, regEventErrorHandler, regGlobalInterceptor, regSub, registerHotReloadCallback, registerTraceCb, setDebugEnabled, setupSubsHotReload, throttleAndDispatch, triggerHotReload, useHotReload, useHotReloadKey, useSubscription };
209
+ export { CoEffectHandler, CoEffects, Context, DISPATCH, DISPATCH_LATER, Db, DispatchLaterEffect, EffectHandler, Effects, ErrorHandler, EventHandler, EventVector, HotReloadWrapper, Id, Interceptor, NOW, RANDOM, SubVector, clearGlobalInterceptors, clearHandlers, clearHotReloadCallbacks, clearReactions, clearSubs, debounceAndDispatch, defaultErrorHandler, disableTracing, dispatch, enableTracePrint, enableTracing, getAppDb, getGlobalInterceptors, getHandler, getSubscriptionValue, initAppDb, isDebugEnabled, regCoeffect, regEffect, regEvent, regEventErrorHandler, regGlobalInterceptor, regSub, registerHotReloadCallback, registerTraceCb, setDebugEnabled, setupSubsHotReload, throttleAndDispatch, triggerHotReload, useHotReload, useHotReloadKey, useSubscription };
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ type EventVector = [Id, ...any[]];
7
7
  type EventHandler<T = Record<string, any>> = (coeffects: CoEffects<T>, ...params: any[]) => Effects | void;
8
8
  type EffectHandler = (value: any) => void;
9
9
  type CoEffectHandler<T = Record<string, any>> = (coeffects: CoEffects<T>, value?: any) => CoEffects<T>;
10
- type ErrorHandler = (originalError: Error, reFrameError: Error & {
10
+ type ErrorHandler = (originalError: Error, reflexError: Error & {
11
11
  data: any;
12
12
  }) => void;
13
13
  type SubVector = [Id, ...any[]];
@@ -57,16 +57,16 @@ declare function regEvent<T = Record<string, any>>(id: Id, handler: EventHandler
57
57
  * Only one handler can be registered. Registering a new handler clears the existing handler.
58
58
  *
59
59
  * This handler function has the signature:
60
- * `(originalError: Error, reFrameError: Error & { data: any }) => void`
60
+ * `(originalError: Error, reflexError: Error & { data: any }) => void`
61
61
  *
62
62
  * - `originalError`: A platform-native Error object.
63
63
  * Represents the original error thrown by user code.
64
64
  * This is the error you see when no handler is registered.
65
65
  *
66
- * - `reFrameError`: An Error object with additional data.
66
+ * - `reflexError`: An Error object with additional data.
67
67
  * Includes the stacktrace of reflex's internal functions,
68
68
  * and extra data about the interceptor process.
69
- * Access `reFrameError.data` to get this info.
69
+ * Access `reflexError.data` to get this info.
70
70
  *
71
71
  * The data includes:
72
72
  * - `interceptor`: the `id` of the throwing interceptor.
@@ -77,7 +77,7 @@ declare function regEventErrorHandler(handler: ErrorHandler): void;
77
77
  /**
78
78
  * Default error handler that logs errors to console
79
79
  */
80
- declare function defaultErrorHandler(originalError: Error, reFrameError: Error & {
80
+ declare function defaultErrorHandler(originalError: Error, reflexError: Error & {
81
81
  data: any;
82
82
  }): void;
83
83
 
@@ -85,8 +85,12 @@ declare function regSub<R>(id: Id, computeFn?: (...values: any[]) => R, depsFn?:
85
85
  declare function getSubscriptionValue<T>(subVector: SubVector): T;
86
86
 
87
87
  declare function regEffect(id: string, handler: EffectHandler): void;
88
+ declare const DISPATCH_LATER = "dispatch-later";
89
+ declare const DISPATCH = "dispatch";
88
90
 
89
91
  declare function regCoeffect(id: string, handler: CoEffectHandler): void;
92
+ declare const NOW = "now";
93
+ declare const RANDOM = "random";
90
94
 
91
95
  /**
92
96
  * Register a global interceptor
@@ -202,4 +206,4 @@ declare function disableTracing(): void;
202
206
  declare function registerTraceCb(key: string, cb: TraceCallback): void;
203
207
  declare function enableTracePrint(): void;
204
208
 
205
- export { CoEffectHandler, CoEffects, Context, Db, DispatchLaterEffect, EffectHandler, Effects, ErrorHandler, EventHandler, EventVector, HotReloadWrapper, Id, Interceptor, SubVector, clearGlobalInterceptors, clearHandlers, clearHotReloadCallbacks, clearReactions, clearSubs, debounceAndDispatch, defaultErrorHandler, disableTracing, dispatch, enableTracePrint, enableTracing, getAppDb, getGlobalInterceptors, getHandler, getSubscriptionValue, initAppDb, isDebugEnabled, regCoeffect, regEffect, regEvent, regEventErrorHandler, regGlobalInterceptor, regSub, registerHotReloadCallback, registerTraceCb, setDebugEnabled, setupSubsHotReload, throttleAndDispatch, triggerHotReload, useHotReload, useHotReloadKey, useSubscription };
209
+ export { CoEffectHandler, CoEffects, Context, DISPATCH, DISPATCH_LATER, Db, DispatchLaterEffect, EffectHandler, Effects, ErrorHandler, EventHandler, EventVector, HotReloadWrapper, Id, Interceptor, NOW, RANDOM, SubVector, clearGlobalInterceptors, clearHandlers, clearHotReloadCallbacks, clearReactions, clearSubs, debounceAndDispatch, defaultErrorHandler, disableTracing, dispatch, enableTracePrint, enableTracing, getAppDb, getGlobalInterceptors, getHandler, getSubscriptionValue, initAppDb, isDebugEnabled, regCoeffect, regEffect, regEvent, regEventErrorHandler, regGlobalInterceptor, regSub, registerHotReloadCallback, registerTraceCb, setDebugEnabled, setupSubsHotReload, throttleAndDispatch, triggerHotReload, useHotReload, useHotReloadKey, useSubscription };
package/dist/index.mjs CHANGED
@@ -246,8 +246,8 @@ function execute(eventV, interceptors) {
246
246
  try {
247
247
  return executeInterceptors(ctx);
248
248
  } catch (e) {
249
- const reFrameError = mergeExData(e, { eventV });
250
- errorHandler(e.cause || e, reFrameError);
249
+ const reflexError = mergeExData(e, { eventV });
250
+ errorHandler(e.cause || e, reflexError);
251
251
  return ctx;
252
252
  }
253
253
  }
@@ -275,11 +275,13 @@ function getInjectCofxInterceptor(id, value) {
275
275
  }
276
276
  };
277
277
  }
278
- regCoeffect("now", (coeffects) => ({
278
+ var NOW = "now";
279
+ var RANDOM = "random";
280
+ regCoeffect(NOW, (coeffects) => ({
279
281
  ...coeffects,
280
282
  now: Date.now()
281
283
  }));
282
- regCoeffect("random", (coeffects) => ({
284
+ regCoeffect(RANDOM, (coeffects) => ({
283
285
  ...coeffects,
284
286
  random: Math.random()
285
287
  }));
@@ -464,6 +466,8 @@ var doFxInterceptor = {
464
466
  return context;
465
467
  }
466
468
  };
469
+ var DISPATCH_LATER = "dispatch-later";
470
+ var DISPATCH = "dispatch";
467
471
  function dispatchLater(effect) {
468
472
  const { ms, dispatch: eventToDispatch } = effect;
469
473
  if (!Array.isArray(eventToDispatch) || typeof ms !== "number") {
@@ -475,10 +479,10 @@ function dispatchLater(effect) {
475
479
  }
476
480
  setTimeout(() => dispatch(eventToDispatch), Math.max(0, ms));
477
481
  }
478
- regEffect("dispatch-later", (value) => {
482
+ regEffect(DISPATCH_LATER, (value) => {
479
483
  dispatchLater(value);
480
484
  });
481
- regEffect("dispatch", (value) => {
485
+ regEffect(DISPATCH, (value) => {
482
486
  if (!Array.isArray(value)) {
483
487
  consoleLog("error", "[reflex] ignoring bad dispatch value. Expected a vector, but got:", value);
484
488
  return;
@@ -559,9 +563,7 @@ function resetTracing() {
559
563
  }
560
564
  function registerTraceCb(key, cb) {
561
565
  if (!traceEnabled) {
562
- console.warn(
563
- "Tracing is not enabled; call enableTracing() before registering callbacks"
564
- );
566
+ consoleLog("warn", "[reflex] [trace] Tracing is not enabled; call enableTracing() before registering callbacks");
565
567
  return;
566
568
  }
567
569
  traceCbs.set(key, cb);
@@ -577,7 +579,7 @@ function scheduleFlush() {
577
579
  try {
578
580
  cb(batch);
579
581
  } catch (e) {
580
- console.error("Error in trace callback", e);
582
+ consoleLog("warn", "Error in trace callback", e);
581
583
  }
582
584
  }
583
585
  }, DEBOUNCE_TIME);
@@ -742,11 +744,11 @@ function handle(eventV) {
742
744
  function regEventErrorHandler(handler) {
743
745
  registerHandler("error", "event-handler", handler);
744
746
  }
745
- function defaultErrorHandler(originalError, reFrameError) {
747
+ function defaultErrorHandler(originalError, reflexError) {
746
748
  consoleLog("error", "[reflex] Interceptor Exception:", {
747
749
  originalError,
748
- reFrameError,
749
- data: reFrameError.data
750
+ reflexError,
751
+ data: reflexError.data
750
752
  });
751
753
  throw originalError;
752
754
  }
@@ -903,7 +905,7 @@ var Reaction = class _Reaction {
903
905
  operation: this.subVector?.[0] ?? "",
904
906
  opType: "sub/dispose",
905
907
  tags: {
906
- subVector: this.subVector,
908
+ queryV: this.subVector,
907
909
  reaction: this.id
908
910
  }
909
911
  },
@@ -1129,7 +1131,11 @@ function HotReloadWrapper({ children }) {
1129
1131
  }
1130
1132
  }
1131
1133
  export {
1134
+ DISPATCH,
1135
+ DISPATCH_LATER,
1132
1136
  HotReloadWrapper,
1137
+ NOW,
1138
+ RANDOM,
1133
1139
  clearGlobalInterceptors,
1134
1140
  clearHandlers,
1135
1141
  clearHotReloadCallbacks,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flexsurfer/reflex",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",