@veams/status-quo 1.6.0 → 1.8.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 (100) hide show
  1. package/.turbo/turbo-build.log +3 -3
  2. package/.turbo/turbo-check$colon$types.log +1 -1
  3. package/.turbo/turbo-lint.log +2 -2
  4. package/.turbo/turbo-test.log +115 -15
  5. package/CHANGELOG.md +2 -0
  6. package/README.md +51 -7
  7. package/dist/config/status-quo-config.d.ts +22 -1
  8. package/dist/config/status-quo-config.js +46 -2
  9. package/dist/config/status-quo-config.js.map +1 -1
  10. package/dist/index.d.ts +12 -2
  11. package/dist/index.js +22 -2
  12. package/dist/index.js.map +1 -1
  13. package/dist/react/hooks/__tests__/state-provider.spec.js +2 -2
  14. package/dist/react/hooks/__tests__/state-provider.spec.js.map +1 -1
  15. package/dist/react/hooks/__tests__/state-selector.spec.js +48 -0
  16. package/dist/react/hooks/__tests__/state-selector.spec.js.map +1 -1
  17. package/dist/react/hooks/index.d.ts +6 -3
  18. package/dist/react/hooks/index.js +12 -3
  19. package/dist/react/hooks/index.js.map +1 -1
  20. package/dist/react/hooks/state-actions.d.ts +9 -1
  21. package/dist/react/hooks/state-actions.js +21 -2
  22. package/dist/react/hooks/state-actions.js.map +1 -1
  23. package/dist/react/hooks/state-factory.d.ts +7 -0
  24. package/dist/react/hooks/state-factory.js +23 -1
  25. package/dist/react/hooks/state-factory.js.map +1 -1
  26. package/dist/react/hooks/state-handler.d.ts +4 -0
  27. package/dist/react/hooks/state-handler.js +18 -1
  28. package/dist/react/hooks/state-handler.js.map +1 -1
  29. package/dist/react/hooks/state-provider.d.ts +18 -9
  30. package/dist/react/hooks/state-provider.js +25 -17
  31. package/dist/react/hooks/state-provider.js.map +1 -1
  32. package/dist/react/hooks/state-singleton.d.ts +8 -2
  33. package/dist/react/hooks/state-singleton.js +21 -3
  34. package/dist/react/hooks/state-singleton.js.map +1 -1
  35. package/dist/react/hooks/state-subscription-selector.d.ts +4 -0
  36. package/dist/react/hooks/state-subscription-selector.js +111 -4
  37. package/dist/react/hooks/state-subscription-selector.js.map +1 -1
  38. package/dist/react/hooks/state-subscription.d.ts +12 -0
  39. package/dist/react/hooks/state-subscription.js +49 -1
  40. package/dist/react/hooks/state-subscription.js.map +1 -1
  41. package/dist/react/index.d.ts +4 -1
  42. package/dist/react/index.js +5 -1
  43. package/dist/react/index.js.map +1 -1
  44. package/dist/store/__tests__/native-state-handler.spec.d.ts +1 -0
  45. package/dist/store/__tests__/native-state-handler.spec.js +210 -0
  46. package/dist/store/__tests__/native-state-handler.spec.js.map +1 -0
  47. package/dist/store/__tests__/observable-state-handler.spec.d.ts +7 -0
  48. package/dist/store/__tests__/observable-state-handler.spec.js.map +1 -1
  49. package/dist/store/base-state-handler.d.ts +42 -0
  50. package/dist/store/base-state-handler.js +73 -10
  51. package/dist/store/base-state-handler.js.map +1 -1
  52. package/dist/store/dev-tools.d.ts +42 -17
  53. package/dist/store/dev-tools.js +24 -8
  54. package/dist/store/dev-tools.js.map +1 -1
  55. package/dist/store/index.d.ts +7 -0
  56. package/dist/store/index.js +9 -0
  57. package/dist/store/index.js.map +1 -1
  58. package/dist/store/native-state-handler.d.ts +44 -0
  59. package/dist/store/native-state-handler.js +62 -0
  60. package/dist/store/native-state-handler.js.map +1 -0
  61. package/dist/store/observable-state-handler.d.ts +34 -0
  62. package/dist/store/observable-state-handler.js +45 -1
  63. package/dist/store/observable-state-handler.js.map +1 -1
  64. package/dist/store/signal-state-handler.d.ts +26 -0
  65. package/dist/store/signal-state-handler.js +35 -0
  66. package/dist/store/signal-state-handler.js.map +1 -1
  67. package/dist/store/state-singleton.d.ts +14 -0
  68. package/dist/store/state-singleton.js +20 -1
  69. package/dist/store/state-singleton.js.map +1 -1
  70. package/dist/types/types.d.ts +9 -0
  71. package/dist/types/types.js +3 -0
  72. package/dist/types/types.js.map +1 -1
  73. package/dist/utils/selector-cache.d.ts +17 -0
  74. package/dist/utils/selector-cache.js +28 -1
  75. package/dist/utils/selector-cache.js.map +1 -1
  76. package/package.json +12 -1
  77. package/src/config/status-quo-config.ts +64 -1
  78. package/src/index.ts +29 -0
  79. package/src/react/hooks/__tests__/state-provider.spec.tsx +2 -2
  80. package/src/react/hooks/__tests__/state-selector.spec.tsx +66 -0
  81. package/src/react/hooks/index.ts +13 -8
  82. package/src/react/hooks/state-actions.tsx +23 -2
  83. package/src/react/hooks/state-factory.tsx +34 -0
  84. package/src/react/hooks/state-handler.tsx +15 -0
  85. package/src/react/hooks/state-provider.tsx +36 -40
  86. package/src/react/hooks/state-singleton.tsx +37 -7
  87. package/src/react/hooks/state-subscription-selector.tsx +151 -3
  88. package/src/react/hooks/state-subscription.tsx +75 -0
  89. package/src/react/index.ts +16 -1
  90. package/src/store/__tests__/native-state-handler.spec.ts +291 -0
  91. package/src/store/__tests__/observable-state-handler.spec.ts +8 -0
  92. package/src/store/base-state-handler.ts +89 -12
  93. package/src/store/dev-tools.ts +72 -27
  94. package/src/store/index.ts +16 -0
  95. package/src/store/native-state-handler.ts +98 -0
  96. package/src/store/observable-state-handler.ts +57 -0
  97. package/src/store/signal-state-handler.ts +47 -1
  98. package/src/store/state-singleton.ts +30 -0
  99. package/src/types/types.ts +16 -0
  100. package/src/utils/selector-cache.ts +37 -0
@@ -1,90 +1,153 @@
1
+ /**
2
+ * Import internal configuration and utility functions.
3
+ */
1
4
  import { resolveDevToolsOptions } from '../config/status-quo-config.js';
2
5
  import { createSelectorCache, selectWithCache } from '../utils/selector-cache.js';
3
6
  import { withDevTools } from './dev-tools.js';
7
+ /**
8
+ * Configuration for Redux DevTools features enabled in this handler.
9
+ */
4
10
  const devToolsFeatures = {
5
- pause: true,
6
- lock: true,
7
- persist: false,
8
- export: true,
9
- import: 'custom',
10
- jump: true,
11
- skip: true,
12
- reorder: true,
13
- dispatch: false,
14
- test: false,
11
+ pause: true, // Allow pausing the recording of actions.
12
+ lock: true, // Allow locking the state.
13
+ persist: false, // Do not persist state across reloads by default.
14
+ export: true, // Allow exporting the state/actions.
15
+ import: 'custom', // Use custom import logic.
16
+ jump: true, // Allow jumping to specific states.
17
+ skip: true, // Allow skipping specific actions.
18
+ reorder: true, // Allow reordering actions.
19
+ dispatch: false, // Do not allow dispatching actions from DevTools.
20
+ test: false, // Do not generate tests.
15
21
  };
22
+ /**
23
+ * Abstract base class for all state handlers in the system.
24
+ * Implements core logic for initialization, DevTools integration, and subscriptions.
25
+ */
16
26
  export class BaseStateHandler {
27
+ // Stores the initial state passed during construction.
17
28
  initialState;
29
+ // Holds the Redux DevTools instance if enabled.
18
30
  devTools = null;
31
+ // Keeps track of active subscriptions to allow for cleanup.
19
32
  subscriptions = [];
33
+ /**
34
+ * Initializes the handler with the given initial state.
35
+ */
20
36
  constructor(initialState) {
21
37
  this.initialState = initialState;
22
38
  }
39
+ /**
40
+ * Sets up Redux DevTools integration based on the provided options.
41
+ */
23
42
  initDevTools(devToolsOptions) {
43
+ // Resolve the final DevTools configuration.
24
44
  const resolvedOptions = resolveDevToolsOptions(devToolsOptions);
45
+ // If DevTools is disabled, stop here.
25
46
  if (!resolvedOptions.enabled) {
26
47
  this.devTools = null;
27
48
  return;
28
49
  }
50
+ // Determine the namespace for the DevTools instance.
29
51
  const namespace = devToolsOptions?.namespace ?? this.getDevToolsNamespace();
52
+ // Connect to the Redux DevTools extension.
30
53
  this.devTools = withDevTools(this.initialState, {
31
54
  name: namespace,
32
55
  instanceId: namespace.toLowerCase().replaceAll(' ', '-'),
33
56
  actionCreators: this.getActions(),
34
57
  features: devToolsFeatures,
35
58
  });
59
+ // Subscribe to events coming from the DevTools extension (e.g., time travel).
36
60
  this.devTools?.subscribe(this.handleDevToolsEvents);
37
61
  }
62
+ /**
63
+ * Returns the initial state of the handler.
64
+ */
38
65
  getInitialState() {
39
66
  return this.initialState;
40
67
  }
68
+ /**
69
+ * Returns the current state.
70
+ */
41
71
  getState() {
42
72
  return this.getStateValue();
43
73
  }
74
+ /**
75
+ * Alias for getState, often used by React's useSyncExternalStore.
76
+ */
44
77
  getSnapshot() {
45
78
  return this.getState();
46
79
  }
80
+ /**
81
+ * Updates the state by merging the partial new state into the current one.
82
+ * Also sends the update to DevTools if enabled.
83
+ */
47
84
  setState(newState, actionName = 'change') {
85
+ // Merge current state with the new partial state.
48
86
  const nextState = { ...this.getState(), ...newState };
87
+ // Update the underlying state value (implemented by subclasses).
49
88
  this.setStateValue(nextState);
89
+ // Notify DevTools of the state change.
50
90
  this.devTools?.send(actionName, nextState);
51
91
  }
92
+ /**
93
+ * Cleans up all active subscriptions when the handler is destroyed.
94
+ */
52
95
  destroy() {
96
+ // Execute the unsubscribe function for each tracked subscription.
53
97
  this.subscriptions.forEach((subscription) => subscription.unsubscribe());
54
98
  }
99
+ /**
100
+ * Returns a default namespace for DevTools based on the class name.
101
+ */
55
102
  getDevToolsNamespace() {
56
103
  return this.constructor.name || 'Store';
57
104
  }
58
105
  bindSubscribable(service, onChange, selector, isEqual = Object.is) {
106
+ // Default to identity selector if none is provided.
59
107
  const selectorFn = (selector ?? ((value) => value));
108
+ // Create a cache for selector results to avoid unnecessary updates.
60
109
  const selectorCache = createSelectorCache();
110
+ // Flag to track if we received an initial value synchronously during subscription.
61
111
  let receivedSyncValue = false;
112
+ // Internal function to handle value changes from the external source.
62
113
  const notifySelectedValue = (value) => {
63
114
  receivedSyncValue = true;
115
+ // Extract the selected value and check if it has actually changed.
64
116
  const { value: nextSelection, hasChanged } = selectWithCache(selectorCache, value, selectorFn, isEqual);
117
+ // Only trigger the callback if the selected value changed.
65
118
  if (!hasChanged) {
66
119
  return;
67
120
  }
68
121
  onChange(nextSelection);
69
122
  };
123
+ // Subscribe to the external source.
70
124
  const unsubscribe = service.subscribe(notifySelectedValue);
125
+ // Track the subscription for later cleanup.
71
126
  this.subscriptions = [...(this.subscriptions ?? []), { unsubscribe }];
127
+ // If the source has a getSnapshot method and we haven't received a value yet, pull it manually.
72
128
  if (service.getSnapshot && !receivedSyncValue)
73
129
  notifySelectedValue(service.getSnapshot());
74
130
  }
131
+ /**
132
+ * Handles messages dispatched from the Redux DevTools extension.
133
+ */
75
134
  handleDevToolsEvents = (message) => {
135
+ // We only care about DISPATCH type messages (e.g., reset, jump).
76
136
  if (message.type !== 'DISPATCH') {
77
137
  return;
78
138
  }
79
139
  switch (message.payload.type) {
140
+ // Revert state to the initial state.
80
141
  case 'RESET':
81
142
  this.setStateValue(this.getInitialState());
82
143
  this.devTools?.init(this.getInitialState());
83
144
  break;
145
+ // Commit the current state in DevTools.
84
146
  case 'COMMIT':
85
147
  this.setStateValue(this.getState());
86
148
  this.devTools?.init(this.getState());
87
149
  break;
150
+ // Handle time travel actions.
88
151
  case 'JUMP_TO_STATE':
89
152
  case 'JUMP_TO_ACTION':
90
153
  this.setStateValue(JSON.parse(message.state));
@@ -1 +1 @@
1
- {"version":3,"file":"base-state-handler.js","sourceRoot":"","sources":["../../src/store/base-state-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base-state-handler.js","sourceRoot":"","sources":["../../src/store/base-state-handler.ts"],"names":[],"mappings":"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"}
@@ -1,23 +1,48 @@
1
- declare global {
2
- interface Window {
3
- __REDUX_DEVTOOLS_EXTENSION__?: {
4
- connect: (opts: Record<string, unknown>) => DevTools;
5
- };
6
- }
7
- }
8
- export type MessagePayload = {
1
+ /**
2
+ * Redux DevTools extension types and constants.
3
+ */
4
+ /**
5
+ * Interface for messages dispatched from the Redux DevTools extension.
6
+ */
7
+ export interface MessagePayload {
9
8
  type: string;
10
9
  payload: {
11
10
  type: string;
12
- actionId: number;
11
+ stateIndex?: number;
12
+ id?: string;
13
13
  };
14
14
  state: string;
15
- id: string;
16
- source: '@devtools-extension';
17
- };
18
- export type DevTools = {
19
- init: (state: unknown) => void;
15
+ }
16
+ /**
17
+ * Interface for the Redux DevTools instance returned by the extension.
18
+ */
19
+ export interface DevTools {
20
20
  send: (action: string, state: unknown) => void;
21
- subscribe: (cb: (message: MessagePayload) => void) => void;
22
- };
23
- export declare function withDevTools<S>(initialState: S, options?: {}): DevTools | null;
21
+ subscribe: (listener: (message: MessagePayload) => void) => () => void;
22
+ init: (state: unknown) => void;
23
+ }
24
+ /**
25
+ * Interface for Redux DevTools connection options.
26
+ */
27
+ export interface DevToolsConnectionOptions {
28
+ name?: string;
29
+ instanceId?: string;
30
+ actionCreators?: unknown;
31
+ features?: {
32
+ pause?: boolean;
33
+ lock?: boolean;
34
+ persist?: boolean;
35
+ export?: boolean | 'custom';
36
+ import?: boolean | 'custom';
37
+ jump?: boolean;
38
+ skip?: boolean;
39
+ reorder?: boolean;
40
+ dispatch?: boolean;
41
+ test?: boolean;
42
+ };
43
+ }
44
+ /**
45
+ * Connects the state handler to the Redux DevTools browser extension.
46
+ * Returns a DevTools object to communicate with the extension.
47
+ */
48
+ export declare function withDevTools(initialState: unknown, options: DevToolsConnectionOptions): DevTools | null;
@@ -1,13 +1,29 @@
1
- export function withDevTools(initialState, options = {}) {
2
- if (typeof window === 'undefined') {
1
+ /**
2
+ * Redux DevTools extension types and constants.
3
+ */
4
+ /**
5
+ * Connects the state handler to the Redux DevTools browser extension.
6
+ * Returns a DevTools object to communicate with the extension.
7
+ */
8
+ export function withDevTools(initialState, options) {
9
+ // Check if the Redux DevTools extension is available in the browser.
10
+ const extension = globalThis?.__REDUX_DEVTOOLS_EXTENSION__;
11
+ // If the extension is not found, we cannot connect.
12
+ if (!extension) {
3
13
  return null;
4
14
  }
5
- if (!window.__REDUX_DEVTOOLS_EXTENSION__) {
6
- console.error('Status Quo :: Devtools Extension is not installed!');
7
- return null;
8
- }
9
- const devTools = window.__REDUX_DEVTOOLS_EXTENSION__.connect(options);
15
+ // Connect to the extension and get an instance.
16
+ const devTools = extension.connect(options);
17
+ // Initialize the DevTools instance with the initial state.
10
18
  devTools.init(initialState);
11
- return devTools;
19
+ // Return an interface to interact with the extension.
20
+ return {
21
+ // Send a new action and state to the DevTools.
22
+ send: (action, state) => devTools.send(action, state),
23
+ // Subscribe to events coming from the DevTools.
24
+ subscribe: (listener) => devTools.subscribe(listener),
25
+ // Re-initialize the state in the extension.
26
+ init: (state) => devTools.init(state),
27
+ };
12
28
  }
13
29
  //# sourceMappingURL=dev-tools.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dev-tools.js","sourceRoot":"","sources":["../../src/store/dev-tools.ts"],"names":[],"mappings":"AAyBA,MAAM,UAAU,YAAY,CAAI,YAAe,EAAE,OAAO,GAAG,EAAE;IAC3D,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAGD,IAAI,CAAC,MAAM,CAAC,4BAA4B,EAAE,CAAC;QACzC,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC;IACd,CAAC;IAGD,MAAM,QAAQ,GAAG,MAAM,CAAC,4BAA4B,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtE,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAG5B,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"dev-tools.js","sourceRoot":"","sources":["../../src/store/dev-tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AA0DH;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,YAAqB,EAAE,OAAkC;IACpF,qEAAqE;IACrE,MAAM,SAAS,GAAI,UAAkB,EAAE,4BAA4B,CAAC;IAEpE,oDAAoD;IACpD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gDAAgD;IAChD,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAE5C,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAE5B,sDAAsD;IACtD,OAAO;QACL,+CAA+C;QAC/C,IAAI,EAAE,CAAC,MAAc,EAAE,KAAc,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;QACtE,gDAAgD;QAChD,SAAS,EAAE,CAAC,QAA2C,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC;QACxF,4CAA4C;QAC5C,IAAI,EAAE,CAAC,KAAc,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;KAC/C,CAAC;AACJ,CAAC"}
@@ -1,5 +1,12 @@
1
+ /**
2
+ * Export core state handler classes and factory functions.
3
+ */
1
4
  export { BaseStateHandler } from './base-state-handler.js';
5
+ export { NativeStateHandler } from './native-state-handler.js';
2
6
  export { ObservableStateHandler } from './observable-state-handler.js';
3
7
  export { SignalStateHandler } from './signal-state-handler.js';
8
+ /**
9
+ * Export singleton related types and factory function.
10
+ */
4
11
  export type { StateSingleton, StateSingletonOptions } from './state-singleton.js';
5
12
  export { makeStateSingleton } from './state-singleton.js';
@@ -1,5 +1,14 @@
1
+ /**
2
+ * Export core state handler classes and factory functions.
3
+ */
4
+ // Export the abstract base class for all state handlers.
1
5
  export { BaseStateHandler } from './base-state-handler.js';
6
+ // Export the lightweight state handler using plain JavaScript.
7
+ export { NativeStateHandler } from './native-state-handler.js';
8
+ // Export the state handler powered by RxJS BehaviorSubjects.
2
9
  export { ObservableStateHandler } from './observable-state-handler.js';
10
+ // Export the state handler powered by Preact Signals.
3
11
  export { SignalStateHandler } from './signal-state-handler.js';
12
+ // Export the factory function to create singleton state handler instances.
4
13
  export { makeStateSingleton } from './state-singleton.js';
5
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,yDAAyD;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,+DAA+D;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,6DAA6D;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,sDAAsD;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAQ/D,2EAA2E;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { BaseStateHandler } from './base-state-handler.js';
2
+ /**
3
+ * Import necessary types for DevTools and distinct update options.
4
+ */
5
+ import type { DevToolsOptions, DistinctOptions } from '../config/status-quo-config.js';
6
+ /**
7
+ * Props for configuring the NativeStateHandler instance.
8
+ */
9
+ type NativeStateHandlerProps<S> = {
10
+ initialState: S;
11
+ options?: {
12
+ devTools?: DevToolsOptions;
13
+ distinct?: DistinctOptions<S>;
14
+ useDistinctUntilChanged?: boolean;
15
+ };
16
+ };
17
+ /**
18
+ * NativeStateHandler: A lightweight state handler using plain JavaScript.
19
+ * Ideal for minimizing dependencies when neither RxJS nor Signals are required.
20
+ */
21
+ export declare abstract class NativeStateHandler<S, A> extends BaseStateHandler<S, A> {
22
+ private state;
23
+ private readonly listeners;
24
+ private readonly distinctOptions;
25
+ /**
26
+ * Initializes the native state handler with given state and configuration.
27
+ */
28
+ protected constructor({ initialState, options }: NativeStateHandlerProps<S>);
29
+ /**
30
+ * Internal implementation of getting the state value.
31
+ */
32
+ protected getStateValue(): S;
33
+ /**
34
+ * Internal implementation of updating the state value.
35
+ */
36
+ protected setStateValue(nextState: S): void;
37
+ /**
38
+ * Subscribes a listener function to state changes.
39
+ * Overloaded to handle both void and state-receiving listeners.
40
+ */
41
+ subscribe(listener: () => void): () => void;
42
+ subscribe(listener: (value: S) => void): () => void;
43
+ }
44
+ export {};
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Import internal configuration and the abstract base state handler.
3
+ */
4
+ import { resolveDistinctOptions } from '../config/status-quo-config.js';
5
+ import { BaseStateHandler } from './base-state-handler.js';
6
+ /**
7
+ * NativeStateHandler: A lightweight state handler using plain JavaScript.
8
+ * Ideal for minimizing dependencies when neither RxJS nor Signals are required.
9
+ */
10
+ export class NativeStateHandler extends BaseStateHandler {
11
+ // The actual state value stored in memory.
12
+ state;
13
+ // A collection of active listeners to notify when the state changes.
14
+ listeners = new Set();
15
+ // Configuration to determine if and how state changes should trigger notifications.
16
+ distinctOptions;
17
+ /**
18
+ * Initializes the native state handler with given state and configuration.
19
+ */
20
+ constructor({ initialState, options }) {
21
+ // Pass the initial state to the base handler.
22
+ super(initialState);
23
+ // Set the initial internal state.
24
+ this.state = initialState;
25
+ // Resolve the final distinct options based on provided configuration.
26
+ this.distinctOptions = resolveDistinctOptions(options?.distinct, options?.useDistinctUntilChanged);
27
+ // Initialize Redux DevTools integration.
28
+ this.initDevTools(options?.devTools);
29
+ }
30
+ /**
31
+ * Internal implementation of getting the state value.
32
+ */
33
+ getStateValue() {
34
+ return this.state;
35
+ }
36
+ /**
37
+ * Internal implementation of updating the state value.
38
+ */
39
+ setStateValue(nextState) {
40
+ // Store the previous state to compare against the new state.
41
+ const previousState = this.state;
42
+ // Update the internal state storage.
43
+ this.state = nextState;
44
+ // If distinct mode is enabled and the state hasn't effectively changed, stop here.
45
+ if (this.distinctOptions.enabled && this.distinctOptions.comparator(previousState, nextState)) {
46
+ return;
47
+ }
48
+ // Notify all active listeners of the state update.
49
+ this.listeners.forEach((listener) => listener(nextState));
50
+ }
51
+ subscribe(listener) {
52
+ // Register the listener to the active set.
53
+ this.listeners.add(listener);
54
+ // Call the listener immediately with the current state to ensure initial consistency.
55
+ listener(this.state);
56
+ // Return an unsubscribe function to remove the listener from the set.
57
+ return () => {
58
+ this.listeners.delete(listener);
59
+ };
60
+ }
61
+ }
62
+ //# sourceMappingURL=native-state-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-state-handler.js","sourceRoot":"","sources":["../../src/store/native-state-handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAqB3D;;;GAGG;AACH,MAAM,OAAgB,kBAAyB,SAAQ,gBAAsB;IAC3E,2CAA2C;IACnC,KAAK,CAAI;IACjB,qEAAqE;IACpD,SAAS,GAA4B,IAAI,GAAG,EAAE,CAAC;IAChE,oFAAoF;IACnE,eAAe,CAA+C;IAE/E;;OAEG;IACH,YAAsB,EAAE,YAAY,EAAE,OAAO,EAA8B;QACzE,8CAA8C;QAC9C,KAAK,CAAC,YAAY,CAAC,CAAC;QACpB,kCAAkC;QAClC,IAAI,CAAC,KAAK,GAAG,YAAY,CAAC;QAC1B,sEAAsE;QACtE,IAAI,CAAC,eAAe,GAAG,sBAAsB,CAC3C,OAAO,EAAE,QAAQ,EACjB,OAAO,EAAE,uBAAuB,CACjC,CAAC;QACF,yCAAyC;QACzC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACO,aAAa;QACrB,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;OAEG;IACO,aAAa,CAAC,SAAY;QAClC,6DAA6D;QAC7D,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC;QACjC,qCAAqC;QACrC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QAEvB,mFAAmF;QACnF,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,IAAI,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,aAAa,EAAE,SAAS,CAAC,EAAE,CAAC;YAC9F,OAAO;QACT,CAAC;QAED,mDAAmD;QACnD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5D,CAAC;IAQD,SAAS,CAAC,QAA4B;QACpC,2CAA2C;QAC3C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE7B,sFAAsF;QACtF,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAErB,sEAAsE;QACtE,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC,CAAC;IACJ,CAAC;CACF"}
@@ -1,6 +1,12 @@
1
1
  import { BaseStateHandler } from './base-state-handler.js';
2
+ /**
3
+ * Import necessary types for DevTools, distinct update options, and RxJS Observable.
4
+ */
2
5
  import type { DevToolsOptions, DistinctOptions } from '../config/status-quo-config.js';
3
6
  import type { Observable } from 'rxjs';
7
+ /**
8
+ * Props for configuring the ObservableStateHandler instance.
9
+ */
4
10
  type ObservableStateHandlerProps<S> = {
5
11
  initialState: S;
6
12
  options?: {
@@ -9,17 +15,45 @@ type ObservableStateHandlerProps<S> = {
9
15
  useDistinctUntilChanged?: boolean;
10
16
  };
11
17
  };
18
+ /**
19
+ * Options for configuring state-related observables.
20
+ */
12
21
  type StateObservableOptions = {
13
22
  useDistinctUntilChanged?: boolean;
14
23
  };
24
+ /**
25
+ * ObservableStateHandler: A state handler built on top of RxJS BehaviorSubject.
26
+ * Provides powerful reactive patterns and integration with RxJS pipelines.
27
+ */
15
28
  export declare abstract class ObservableStateHandler<S, A> extends BaseStateHandler<S, A> {
16
29
  private readonly state$;
17
30
  private readonly distinctOptions;
31
+ /**
32
+ * Initializes the observable state handler with given state and configuration.
33
+ */
18
34
  protected constructor({ initialState, options }: ObservableStateHandlerProps<S>);
35
+ /**
36
+ * Internal implementation of getting the state value via BehaviorSubject.
37
+ */
19
38
  protected getStateValue(): S;
39
+ /**
40
+ * Internal implementation of updating the state value via BehaviorSubject.
41
+ */
20
42
  protected setStateValue(nextState: S): void;
43
+ /**
44
+ * Returns an observable tracking a specific key within the state object.
45
+ * Only emits when the value of the specified key actually changes.
46
+ */
21
47
  getObservableItem<K extends keyof S>(key: K): Observable<S[K]>;
48
+ /**
49
+ * Returns an observable tracking the entire state object.
50
+ * Can be configured to emit only when the state object effectively changes.
51
+ */
22
52
  getObservable(options?: StateObservableOptions): Observable<S>;
53
+ /**
54
+ * Subscribes a listener function to state changes via the internal observable.
55
+ * Overloaded to handle both void and state-receiving listeners.
56
+ */
23
57
  subscribe(listener: () => void): () => void;
24
58
  subscribe(listener: (value: S) => void): () => void;
25
59
  }
@@ -1,37 +1,81 @@
1
+ /**
2
+ * Import RxJS components for reactive state handling.
3
+ */
1
4
  import { BehaviorSubject, distinctUntilChanged, distinctUntilKeyChanged, map } from 'rxjs';
5
+ /**
6
+ * Import internal configuration and the abstract base state handler.
7
+ */
2
8
  import { resolveDistinctOptions } from '../config/status-quo-config.js';
3
9
  import { BaseStateHandler } from './base-state-handler.js';
10
+ /**
11
+ * ObservableStateHandler: A state handler built on top of RxJS BehaviorSubject.
12
+ * Provides powerful reactive patterns and integration with RxJS pipelines.
13
+ */
4
14
  export class ObservableStateHandler extends BaseStateHandler {
15
+ // Internal BehaviorSubject to manage the state and provide current values to new subscribers.
5
16
  state$;
17
+ // Configuration to determine if and how state changes should trigger notifications.
6
18
  distinctOptions;
19
+ /**
20
+ * Initializes the observable state handler with given state and configuration.
21
+ */
7
22
  constructor({ initialState, options }) {
23
+ // Pass the initial state to the base handler.
8
24
  super(initialState);
25
+ // Initialize the internal BehaviorSubject with the initial state.
9
26
  this.state$ = new BehaviorSubject(initialState);
27
+ // Resolve the final distinct options based on provided configuration.
10
28
  this.distinctOptions = resolveDistinctOptions(options?.distinct, options?.useDistinctUntilChanged);
29
+ // Initialize Redux DevTools integration.
11
30
  this.initDevTools(options?.devTools);
12
31
  }
32
+ /**
33
+ * Internal implementation of getting the state value via BehaviorSubject.
34
+ */
13
35
  getStateValue() {
14
36
  return this.state$.getValue();
15
37
  }
38
+ /**
39
+ * Internal implementation of updating the state value via BehaviorSubject.
40
+ */
16
41
  setStateValue(nextState) {
42
+ // Notify the subject and all its subscribers of the new state.
17
43
  this.state$.next(nextState);
18
44
  }
45
+ /**
46
+ * Returns an observable tracking a specific key within the state object.
47
+ * Only emits when the value of the specified key actually changes.
48
+ */
19
49
  getObservableItem(key) {
20
- return this.state$.pipe(distinctUntilKeyChanged(key), map((state) => state[key]));
50
+ return this.state$.pipe(
51
+ // Ensure we only emit if the value associated with the key has changed.
52
+ distinctUntilKeyChanged(key),
53
+ // Transform the state object into the specific key value.
54
+ map((state) => state[key]));
21
55
  }
56
+ /**
57
+ * Returns an observable tracking the entire state object.
58
+ * Can be configured to emit only when the state object effectively changes.
59
+ */
22
60
  getObservable(options = {}) {
61
+ // Determine whether distinct emissions are enabled.
23
62
  const useDistinctUntilChanged = options.useDistinctUntilChanged ?? this.distinctOptions.enabled;
63
+ // If distinct emissions are not enabled, return the subject as-is.
24
64
  if (!useDistinctUntilChanged) {
25
65
  return this.state$;
26
66
  }
67
+ // Apply the distinctUntilChanged operator to filter out redundant updates.
27
68
  return this.state$.pipe(distinctUntilChanged((previous, next) => {
69
+ // Use the resolved comparator to compare the previous and next states.
28
70
  return this.distinctOptions.comparator(previous, next);
29
71
  }));
30
72
  }
31
73
  subscribe(listener) {
74
+ // Subscribe to the state observable and call the listener on each emission.
32
75
  const subscription = this.getObservable().subscribe((nextState) => {
33
76
  listener(nextState);
34
77
  });
78
+ // Return an unsubscribe function to properly clean up the RxJS subscription.
35
79
  return () => subscription.unsubscribe();
36
80
  }
37
81
  }
@@ -1 +1 @@
1
- {"version":3,"file":"observable-state-handler.js","sourceRoot":"","sources":["../../src/store/observable-state-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAE3F,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAgB3D,MAAM,OAAgB,sBAA6B,SAAQ,gBAAsB;IAC9D,MAAM,CAAqB;IAC3B,eAAe,CAA+C;IAE/E,YAAsB,EAAE,YAAY,EAAE,OAAO,EAAkC;QAC7E,KAAK,CAAC,YAAY,CAAC,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,eAAe,CAAI,YAAY,CAAC,CAAC;QACnD,IAAI,CAAC,eAAe,GAAG,sBAAsB,CAC3C,OAAO,EAAE,QAAQ,EACjB,OAAO,EAAE,uBAAuB,CACjC,CAAC;QACF,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACvC,CAAC;IAES,aAAa;QACrB,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;IAChC,CAAC;IAES,aAAa,CAAC,SAAY;QAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC;IAED,iBAAiB,CAAoB,GAAM;QACzC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CACrB,uBAAuB,CAAC,GAAG,CAAC,EAC5B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAC3B,CAAC;IACJ,CAAC;IAED,aAAa,CAAC,UAAkC,EAAE;QAChD,MAAM,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;QAEhG,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CACrB,oBAAoB,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE;YACtC,OAAO,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACzD,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAID,SAAS,CAAC,QAA4B;QACpC,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE;YAChE,QAAQ,CAAC,SAAS,CAAC,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;IAC1C,CAAC;CACF"}
1
+ {"version":3,"file":"observable-state-handler.js","sourceRoot":"","sources":["../../src/store/observable-state-handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAE3F;;GAEG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AA2B3D;;;GAGG;AACH,MAAM,OAAgB,sBAA6B,SAAQ,gBAAsB;IAC/E,8FAA8F;IAC7E,MAAM,CAAqB;IAC5C,oFAAoF;IACnE,eAAe,CAA+C;IAE/E;;OAEG;IACH,YAAsB,EAAE,YAAY,EAAE,OAAO,EAAkC;QAC7E,8CAA8C;QAC9C,KAAK,CAAC,YAAY,CAAC,CAAC;QACpB,kEAAkE;QAClE,IAAI,CAAC,MAAM,GAAG,IAAI,eAAe,CAAI,YAAY,CAAC,CAAC;QACnD,sEAAsE;QACtE,IAAI,CAAC,eAAe,GAAG,sBAAsB,CAC3C,OAAO,EAAE,QAAQ,EACjB,OAAO,EAAE,uBAAuB,CACjC,CAAC;QACF,yCAAyC;QACzC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACO,aAAa;QACrB,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;IAChC,CAAC;IAED;;OAEG;IACO,aAAa,CAAC,SAAY;QAClC,+DAA+D;QAC/D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC;IAED;;;OAGG;IACH,iBAAiB,CAAoB,GAAM;QACzC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI;QACrB,wEAAwE;QACxE,uBAAuB,CAAC,GAAG,CAAC;QAC5B,0DAA0D;QAC1D,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAC3B,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,UAAkC,EAAE;QAChD,oDAAoD;QACpD,MAAM,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;QAEhG,mEAAmE;QACnE,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;QAED,2EAA2E;QAC3E,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CACrB,oBAAoB,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE;YACtC,uEAAuE;YACvE,OAAO,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACzD,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAQD,SAAS,CAAC,QAA4B;QACpC,4EAA4E;QAC5E,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE;YAChE,QAAQ,CAAC,SAAS,CAAC,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,6EAA6E;QAC7E,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;IAC1C,CAAC;CACF"}
@@ -1,6 +1,12 @@
1
1
  import { BaseStateHandler } from './base-state-handler.js';
2
+ /**
3
+ * Import necessary types for DevTools, distinct update options, and Preact Signals.
4
+ */
2
5
  import type { DevToolsOptions, DistinctOptions } from '../config/status-quo-config.js';
3
6
  import type { Signal } from '@preact/signals-core';
7
+ /**
8
+ * Props for configuring the SignalStateHandler instance.
9
+ */
4
10
  type SignalStateHandlerProps<S> = {
5
11
  initialState: S;
6
12
  options?: {
@@ -9,14 +15,34 @@ type SignalStateHandlerProps<S> = {
9
15
  useDistinctUntilChanged?: boolean;
10
16
  };
11
17
  };
18
+ /**
19
+ * SignalStateHandler: A state handler built on top of Preact Signals.
20
+ * Provides fine-grained reactivity and efficient state updates.
21
+ */
12
22
  export declare abstract class SignalStateHandler<S, A> extends BaseStateHandler<S, A> {
13
23
  private readonly state;
14
24
  private readonly distinctOptions;
25
+ /**
26
+ * Initializes the signal state handler with given state and configuration.
27
+ */
15
28
  protected constructor({ initialState, options }: SignalStateHandlerProps<S>);
29
+ /**
30
+ * Returns the underlying signal for external use (e.g., in reactive templates).
31
+ */
16
32
  getSignal(): Signal<S>;
33
+ /**
34
+ * Subscribes a listener function to state changes via the internal signal.
35
+ * Overloaded to handle both void and state-receiving listeners.
36
+ */
17
37
  subscribe(listener: () => void): () => void;
18
38
  subscribe(listener: (value: S) => void): () => void;
39
+ /**
40
+ * Internal implementation of getting the state value via the Signal's value property.
41
+ */
19
42
  protected getStateValue(): S;
43
+ /**
44
+ * Internal implementation of updating the state value via the Signal's value property.
45
+ */
20
46
  protected setStateValue(nextState: S): void;
21
47
  }
22
48
  export {};