@voidhash/mimic-react 0.0.1 → 0.0.3

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 (61) hide show
  1. package/.turbo/turbo-build.log +60 -26
  2. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/defineProperty.cjs +14 -0
  3. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/defineProperty.mjs +14 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/objectSpread2.cjs +27 -0
  5. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/objectSpread2.mjs +27 -0
  6. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/toPrimitive.cjs +16 -0
  7. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/toPrimitive.mjs +16 -0
  8. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/toPropertyKey.cjs +11 -0
  9. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/toPropertyKey.mjs +11 -0
  10. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/typeof.cjs +18 -0
  11. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/typeof.mjs +12 -0
  12. package/dist/zustand/index.cjs +2 -94
  13. package/dist/zustand/index.d.cts +3 -115
  14. package/dist/zustand/index.d.mts +3 -115
  15. package/dist/zustand/index.mjs +2 -95
  16. package/dist/zustand/middleware.cjs +95 -0
  17. package/dist/zustand/middleware.d.cts +47 -0
  18. package/dist/zustand/middleware.d.cts.map +1 -0
  19. package/dist/zustand/middleware.d.mts +47 -0
  20. package/dist/zustand/middleware.d.mts.map +1 -0
  21. package/dist/zustand/middleware.mjs +96 -0
  22. package/dist/zustand/middleware.mjs.map +1 -0
  23. package/dist/zustand/types.d.cts +75 -0
  24. package/dist/zustand/types.d.cts.map +1 -0
  25. package/dist/zustand/types.d.mts +75 -0
  26. package/dist/zustand/types.d.mts.map +1 -0
  27. package/dist/zustand-commander/commander.cjs +187 -0
  28. package/dist/zustand-commander/commander.d.cts +52 -0
  29. package/dist/zustand-commander/commander.d.cts.map +1 -0
  30. package/dist/zustand-commander/commander.d.mts +52 -0
  31. package/dist/zustand-commander/commander.d.mts.map +1 -0
  32. package/dist/zustand-commander/commander.mjs +185 -0
  33. package/dist/zustand-commander/commander.mjs.map +1 -0
  34. package/dist/zustand-commander/hooks.cjs +145 -0
  35. package/dist/zustand-commander/hooks.d.cts +78 -0
  36. package/dist/zustand-commander/hooks.d.cts.map +1 -0
  37. package/dist/zustand-commander/hooks.d.mts +78 -0
  38. package/dist/zustand-commander/hooks.d.mts.map +1 -0
  39. package/dist/zustand-commander/hooks.mjs +144 -0
  40. package/dist/zustand-commander/hooks.mjs.map +1 -0
  41. package/dist/zustand-commander/index.cjs +15 -354
  42. package/dist/zustand-commander/index.d.cts +4 -313
  43. package/dist/zustand-commander/index.d.mts +4 -313
  44. package/dist/zustand-commander/index.mjs +4 -344
  45. package/dist/zustand-commander/types.cjs +28 -0
  46. package/dist/zustand-commander/types.d.cts +195 -0
  47. package/dist/zustand-commander/types.d.cts.map +1 -0
  48. package/dist/zustand-commander/types.d.mts +195 -0
  49. package/dist/zustand-commander/types.d.mts.map +1 -0
  50. package/dist/zustand-commander/types.mjs +25 -0
  51. package/dist/zustand-commander/types.mjs.map +1 -0
  52. package/package.json +3 -3
  53. package/tsdown.config.ts +1 -1
  54. package/dist/objectSpread2-CIP_6jda.cjs +0 -73
  55. package/dist/objectSpread2-CxTyNSYl.mjs +0 -67
  56. package/dist/zustand/index.d.cts.map +0 -1
  57. package/dist/zustand/index.d.mts.map +0 -1
  58. package/dist/zustand/index.mjs.map +0 -1
  59. package/dist/zustand-commander/index.d.cts.map +0 -1
  60. package/dist/zustand-commander/index.d.mts.map +0 -1
  61. package/dist/zustand-commander/index.mjs.map +0 -1
@@ -0,0 +1,187 @@
1
+ const require_objectSpread2 = require('../_virtual/_@oxc-project_runtime@0.103.0/helpers/objectSpread2.cjs');
2
+ const require_types = require('./types.cjs');
3
+
4
+ //#region src/zustand-commander/commander.ts
5
+ const DEFAULT_OPTIONS = { maxUndoStackSize: 100 };
6
+ /**
7
+ * Creates a commander instance bound to a specific store type.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * // Create commander for your store type
12
+ * const commander = createCommander<StoreState>();
13
+ *
14
+ * // Define commands
15
+ * const addItem = commander.action(
16
+ * Schema.Struct({ name: Schema.String }),
17
+ * (ctx, params) => {
18
+ * const { mimic } = ctx.getState();
19
+ * mimic.document.transaction(root => {
20
+ * // add item
21
+ * });
22
+ * }
23
+ * );
24
+ *
25
+ * // Create store with middleware
26
+ * const useStore = create(
27
+ * commander.middleware(
28
+ * mimic(document, (set, get) => ({
29
+ * // your state
30
+ * }))
31
+ * )
32
+ * );
33
+ * ```
34
+ */
35
+ function createCommander(options = {}) {
36
+ const { maxUndoStackSize } = require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, DEFAULT_OPTIONS), options);
37
+ let _storeApi = null;
38
+ /**
39
+ * Creates the dispatch function for use within command handlers.
40
+ */
41
+ const createDispatch = () => {
42
+ return (command) => {
43
+ return (params) => {
44
+ if (!_storeApi) throw new Error("Commander: Store not initialized. Make sure to use the commander middleware.");
45
+ const ctx = {
46
+ getState: () => _storeApi.getState(),
47
+ setState: (partial) => _storeApi.setState(partial),
48
+ dispatch: createDispatch()
49
+ };
50
+ const result = command.fn(ctx, params);
51
+ if (require_types.isUndoableCommand(command)) {
52
+ const entry = {
53
+ command,
54
+ params,
55
+ result,
56
+ timestamp: Date.now()
57
+ };
58
+ _storeApi.setState((state) => {
59
+ const { undoStack, redoStack } = state._commander;
60
+ const newUndoStack = [...undoStack, entry].slice(-maxUndoStackSize);
61
+ return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, state), {}, { _commander: {
62
+ undoStack: newUndoStack,
63
+ redoStack: []
64
+ } });
65
+ });
66
+ }
67
+ return result;
68
+ };
69
+ };
70
+ };
71
+ /**
72
+ * Create a regular command (no undo support).
73
+ */
74
+ function action(fn) {
75
+ return {
76
+ [require_types.COMMAND_SYMBOL]: true,
77
+ fn
78
+ };
79
+ }
80
+ /**
81
+ * Create an undoable command with undo/redo support.
82
+ */
83
+ function undoableAction(fn, revert) {
84
+ return {
85
+ [require_types.COMMAND_SYMBOL]: true,
86
+ [require_types.UNDOABLE_COMMAND_SYMBOL]: true,
87
+ fn,
88
+ revert
89
+ };
90
+ }
91
+ /**
92
+ * Zustand middleware that adds commander functionality.
93
+ */
94
+ const middleware = (config) => {
95
+ return (set, get, api) => {
96
+ _storeApi = api;
97
+ return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, config(set, get, api)), {}, { _commander: {
98
+ undoStack: [],
99
+ redoStack: []
100
+ } });
101
+ };
102
+ };
103
+ return {
104
+ action,
105
+ undoableAction,
106
+ middleware
107
+ };
108
+ }
109
+ /**
110
+ * Perform an undo operation on the store.
111
+ * Returns true if an undo was performed, false if undo stack was empty.
112
+ */
113
+ function performUndo(storeApi) {
114
+ const { undoStack, redoStack } = storeApi.getState()._commander;
115
+ const entry = undoStack[undoStack.length - 1];
116
+ if (!entry) return false;
117
+ const newUndoStack = undoStack.slice(0, -1);
118
+ const ctx = {
119
+ getState: () => storeApi.getState(),
120
+ setState: (partial) => storeApi.setState(partial),
121
+ dispatch: createDispatchForUndo(storeApi)
122
+ };
123
+ entry.command.revert(ctx, entry.params, entry.result);
124
+ storeApi.setState((state) => require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, state), {}, { _commander: {
125
+ undoStack: newUndoStack,
126
+ redoStack: [...redoStack, entry]
127
+ } }));
128
+ return true;
129
+ }
130
+ /**
131
+ * Perform a redo operation on the store.
132
+ * Returns true if a redo was performed, false if redo stack was empty.
133
+ */
134
+ function performRedo(storeApi) {
135
+ const { undoStack, redoStack } = storeApi.getState()._commander;
136
+ const entry = redoStack[redoStack.length - 1];
137
+ if (!entry) return false;
138
+ const newRedoStack = redoStack.slice(0, -1);
139
+ const ctx = {
140
+ getState: () => storeApi.getState(),
141
+ setState: (partial) => storeApi.setState(partial),
142
+ dispatch: createDispatchForUndo(storeApi)
143
+ };
144
+ const result = entry.command.fn(ctx, entry.params);
145
+ const newEntry = {
146
+ command: entry.command,
147
+ params: entry.params,
148
+ result,
149
+ timestamp: Date.now()
150
+ };
151
+ storeApi.setState((state) => require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, state), {}, { _commander: {
152
+ undoStack: [...undoStack, newEntry],
153
+ redoStack: newRedoStack
154
+ } }));
155
+ return true;
156
+ }
157
+ /**
158
+ * Creates a dispatch function for use during undo/redo operations.
159
+ * This dispatch does NOT add to undo stack (to avoid infinite loops).
160
+ */
161
+ function createDispatchForUndo(storeApi) {
162
+ return (command) => {
163
+ return (params) => {
164
+ const ctx = {
165
+ getState: () => storeApi.getState(),
166
+ setState: (partial) => storeApi.setState(partial),
167
+ dispatch: createDispatchForUndo(storeApi)
168
+ };
169
+ return command.fn(ctx, params);
170
+ };
171
+ };
172
+ }
173
+ /**
174
+ * Clear the undo and redo stacks.
175
+ */
176
+ function clearUndoHistory(storeApi) {
177
+ storeApi.setState((state) => require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, state), {}, { _commander: {
178
+ undoStack: [],
179
+ redoStack: []
180
+ } }));
181
+ }
182
+
183
+ //#endregion
184
+ exports.clearUndoHistory = clearUndoHistory;
185
+ exports.createCommander = createCommander;
186
+ exports.performRedo = performRedo;
187
+ exports.performUndo = performUndo;
@@ -0,0 +1,52 @@
1
+ import { Commander, CommanderOptions, CommanderSlice } from "./types.cjs";
2
+ import { StoreApi } from "zustand";
3
+
4
+ //#region src/zustand-commander/commander.d.ts
5
+
6
+ /**
7
+ * Creates a commander instance bound to a specific store type.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * // Create commander for your store type
12
+ * const commander = createCommander<StoreState>();
13
+ *
14
+ * // Define commands
15
+ * const addItem = commander.action(
16
+ * Schema.Struct({ name: Schema.String }),
17
+ * (ctx, params) => {
18
+ * const { mimic } = ctx.getState();
19
+ * mimic.document.transaction(root => {
20
+ * // add item
21
+ * });
22
+ * }
23
+ * );
24
+ *
25
+ * // Create store with middleware
26
+ * const useStore = create(
27
+ * commander.middleware(
28
+ * mimic(document, (set, get) => ({
29
+ * // your state
30
+ * }))
31
+ * )
32
+ * );
33
+ * ```
34
+ */
35
+ declare function createCommander<TStore extends object>(options?: CommanderOptions): Commander<TStore & CommanderSlice>;
36
+ /**
37
+ * Perform an undo operation on the store.
38
+ * Returns true if an undo was performed, false if undo stack was empty.
39
+ */
40
+ declare function performUndo<TStore extends CommanderSlice>(storeApi: StoreApi<TStore>): boolean;
41
+ /**
42
+ * Perform a redo operation on the store.
43
+ * Returns true if a redo was performed, false if redo stack was empty.
44
+ */
45
+ declare function performRedo<TStore extends CommanderSlice>(storeApi: StoreApi<TStore>): boolean;
46
+ /**
47
+ * Clear the undo and redo stacks.
48
+ */
49
+ declare function clearUndoHistory<TStore extends CommanderSlice>(storeApi: StoreApi<TStore>): void;
50
+ //#endregion
51
+ export { clearUndoHistory, createCommander, performRedo, performUndo };
52
+ //# sourceMappingURL=commander.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commander.d.cts","names":[],"sources":["../../src/zustand-commander/commander.ts"],"sourcesContent":[],"mappings":";;;;;;AA2MA;;;;;AAwCA;;;;;AAoEA;;;;;;;;;;;;;;;;;;iBArPgB,iDACL,mBACR,UAAU,SAAS;;;;;iBAuIN,2BAA2B,0BAC/B,SAAS;;;;;iBAuCL,2BAA2B,0BAC/B,SAAS;;;;iBAmEL,gCAAgC,0BACpC,SAAS"}
@@ -0,0 +1,52 @@
1
+ import { Commander, CommanderOptions, CommanderSlice } from "./types.mjs";
2
+ import { StoreApi } from "zustand";
3
+
4
+ //#region src/zustand-commander/commander.d.ts
5
+
6
+ /**
7
+ * Creates a commander instance bound to a specific store type.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * // Create commander for your store type
12
+ * const commander = createCommander<StoreState>();
13
+ *
14
+ * // Define commands
15
+ * const addItem = commander.action(
16
+ * Schema.Struct({ name: Schema.String }),
17
+ * (ctx, params) => {
18
+ * const { mimic } = ctx.getState();
19
+ * mimic.document.transaction(root => {
20
+ * // add item
21
+ * });
22
+ * }
23
+ * );
24
+ *
25
+ * // Create store with middleware
26
+ * const useStore = create(
27
+ * commander.middleware(
28
+ * mimic(document, (set, get) => ({
29
+ * // your state
30
+ * }))
31
+ * )
32
+ * );
33
+ * ```
34
+ */
35
+ declare function createCommander<TStore extends object>(options?: CommanderOptions): Commander<TStore & CommanderSlice>;
36
+ /**
37
+ * Perform an undo operation on the store.
38
+ * Returns true if an undo was performed, false if undo stack was empty.
39
+ */
40
+ declare function performUndo<TStore extends CommanderSlice>(storeApi: StoreApi<TStore>): boolean;
41
+ /**
42
+ * Perform a redo operation on the store.
43
+ * Returns true if a redo was performed, false if redo stack was empty.
44
+ */
45
+ declare function performRedo<TStore extends CommanderSlice>(storeApi: StoreApi<TStore>): boolean;
46
+ /**
47
+ * Clear the undo and redo stacks.
48
+ */
49
+ declare function clearUndoHistory<TStore extends CommanderSlice>(storeApi: StoreApi<TStore>): void;
50
+ //#endregion
51
+ export { clearUndoHistory, createCommander, performRedo, performUndo };
52
+ //# sourceMappingURL=commander.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commander.d.mts","names":[],"sources":["../../src/zustand-commander/commander.ts"],"sourcesContent":[],"mappings":";;;;;;AA2MA;;;;;AAwCA;;;;;AAoEA;;;;;;;;;;;;;;;;;;iBArPgB,iDACL,mBACR,UAAU,SAAS;;;;;iBAuIN,2BAA2B,0BAC/B,SAAS;;;;;iBAuCL,2BAA2B,0BAC/B,SAAS;;;;iBAmEL,gCAAgC,0BACpC,SAAS"}
@@ -0,0 +1,185 @@
1
+ import { _objectSpread2 } from "../_virtual/_@oxc-project_runtime@0.103.0/helpers/objectSpread2.mjs";
2
+ import { COMMAND_SYMBOL, UNDOABLE_COMMAND_SYMBOL, isUndoableCommand } from "./types.mjs";
3
+
4
+ //#region src/zustand-commander/commander.ts
5
+ const DEFAULT_OPTIONS = { maxUndoStackSize: 100 };
6
+ /**
7
+ * Creates a commander instance bound to a specific store type.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * // Create commander for your store type
12
+ * const commander = createCommander<StoreState>();
13
+ *
14
+ * // Define commands
15
+ * const addItem = commander.action(
16
+ * Schema.Struct({ name: Schema.String }),
17
+ * (ctx, params) => {
18
+ * const { mimic } = ctx.getState();
19
+ * mimic.document.transaction(root => {
20
+ * // add item
21
+ * });
22
+ * }
23
+ * );
24
+ *
25
+ * // Create store with middleware
26
+ * const useStore = create(
27
+ * commander.middleware(
28
+ * mimic(document, (set, get) => ({
29
+ * // your state
30
+ * }))
31
+ * )
32
+ * );
33
+ * ```
34
+ */
35
+ function createCommander(options = {}) {
36
+ const { maxUndoStackSize } = _objectSpread2(_objectSpread2({}, DEFAULT_OPTIONS), options);
37
+ let _storeApi = null;
38
+ /**
39
+ * Creates the dispatch function for use within command handlers.
40
+ */
41
+ const createDispatch = () => {
42
+ return (command) => {
43
+ return (params) => {
44
+ if (!_storeApi) throw new Error("Commander: Store not initialized. Make sure to use the commander middleware.");
45
+ const ctx = {
46
+ getState: () => _storeApi.getState(),
47
+ setState: (partial) => _storeApi.setState(partial),
48
+ dispatch: createDispatch()
49
+ };
50
+ const result = command.fn(ctx, params);
51
+ if (isUndoableCommand(command)) {
52
+ const entry = {
53
+ command,
54
+ params,
55
+ result,
56
+ timestamp: Date.now()
57
+ };
58
+ _storeApi.setState((state) => {
59
+ const { undoStack, redoStack } = state._commander;
60
+ const newUndoStack = [...undoStack, entry].slice(-maxUndoStackSize);
61
+ return _objectSpread2(_objectSpread2({}, state), {}, { _commander: {
62
+ undoStack: newUndoStack,
63
+ redoStack: []
64
+ } });
65
+ });
66
+ }
67
+ return result;
68
+ };
69
+ };
70
+ };
71
+ /**
72
+ * Create a regular command (no undo support).
73
+ */
74
+ function action(fn) {
75
+ return {
76
+ [COMMAND_SYMBOL]: true,
77
+ fn
78
+ };
79
+ }
80
+ /**
81
+ * Create an undoable command with undo/redo support.
82
+ */
83
+ function undoableAction(fn, revert) {
84
+ return {
85
+ [COMMAND_SYMBOL]: true,
86
+ [UNDOABLE_COMMAND_SYMBOL]: true,
87
+ fn,
88
+ revert
89
+ };
90
+ }
91
+ /**
92
+ * Zustand middleware that adds commander functionality.
93
+ */
94
+ const middleware = (config) => {
95
+ return (set, get, api) => {
96
+ _storeApi = api;
97
+ return _objectSpread2(_objectSpread2({}, config(set, get, api)), {}, { _commander: {
98
+ undoStack: [],
99
+ redoStack: []
100
+ } });
101
+ };
102
+ };
103
+ return {
104
+ action,
105
+ undoableAction,
106
+ middleware
107
+ };
108
+ }
109
+ /**
110
+ * Perform an undo operation on the store.
111
+ * Returns true if an undo was performed, false if undo stack was empty.
112
+ */
113
+ function performUndo(storeApi) {
114
+ const { undoStack, redoStack } = storeApi.getState()._commander;
115
+ const entry = undoStack[undoStack.length - 1];
116
+ if (!entry) return false;
117
+ const newUndoStack = undoStack.slice(0, -1);
118
+ const ctx = {
119
+ getState: () => storeApi.getState(),
120
+ setState: (partial) => storeApi.setState(partial),
121
+ dispatch: createDispatchForUndo(storeApi)
122
+ };
123
+ entry.command.revert(ctx, entry.params, entry.result);
124
+ storeApi.setState((state) => _objectSpread2(_objectSpread2({}, state), {}, { _commander: {
125
+ undoStack: newUndoStack,
126
+ redoStack: [...redoStack, entry]
127
+ } }));
128
+ return true;
129
+ }
130
+ /**
131
+ * Perform a redo operation on the store.
132
+ * Returns true if a redo was performed, false if redo stack was empty.
133
+ */
134
+ function performRedo(storeApi) {
135
+ const { undoStack, redoStack } = storeApi.getState()._commander;
136
+ const entry = redoStack[redoStack.length - 1];
137
+ if (!entry) return false;
138
+ const newRedoStack = redoStack.slice(0, -1);
139
+ const ctx = {
140
+ getState: () => storeApi.getState(),
141
+ setState: (partial) => storeApi.setState(partial),
142
+ dispatch: createDispatchForUndo(storeApi)
143
+ };
144
+ const result = entry.command.fn(ctx, entry.params);
145
+ const newEntry = {
146
+ command: entry.command,
147
+ params: entry.params,
148
+ result,
149
+ timestamp: Date.now()
150
+ };
151
+ storeApi.setState((state) => _objectSpread2(_objectSpread2({}, state), {}, { _commander: {
152
+ undoStack: [...undoStack, newEntry],
153
+ redoStack: newRedoStack
154
+ } }));
155
+ return true;
156
+ }
157
+ /**
158
+ * Creates a dispatch function for use during undo/redo operations.
159
+ * This dispatch does NOT add to undo stack (to avoid infinite loops).
160
+ */
161
+ function createDispatchForUndo(storeApi) {
162
+ return (command) => {
163
+ return (params) => {
164
+ const ctx = {
165
+ getState: () => storeApi.getState(),
166
+ setState: (partial) => storeApi.setState(partial),
167
+ dispatch: createDispatchForUndo(storeApi)
168
+ };
169
+ return command.fn(ctx, params);
170
+ };
171
+ };
172
+ }
173
+ /**
174
+ * Clear the undo and redo stacks.
175
+ */
176
+ function clearUndoHistory(storeApi) {
177
+ storeApi.setState((state) => _objectSpread2(_objectSpread2({}, state), {}, { _commander: {
178
+ undoStack: [],
179
+ redoStack: []
180
+ } }));
181
+ }
182
+
183
+ //#endregion
184
+ export { clearUndoHistory, createCommander, performRedo, performUndo };
185
+ //# sourceMappingURL=commander.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commander.mjs","names":["DEFAULT_OPTIONS: Required<CommanderOptions>","_storeApi: StoreApi<TStore & CommanderSlice> | null","ctx: CommandContext<TStore & CommanderSlice>","entry: UndoEntry<TParams, TReturn>","ctx: CommandContext<TStore>","newEntry: UndoEntry"],"sources":["../../src/zustand-commander/commander.ts"],"sourcesContent":["/**\n * @voidhash/mimic-react/zustand-commander\n *\n * Commander creation and command definition.\n *\n * @since 0.0.1\n */\n\nimport type { StoreApi } from \"zustand\";\nimport {\n COMMAND_SYMBOL,\n UNDOABLE_COMMAND_SYMBOL,\n isUndoableCommand,\n type Command,\n type Commander,\n type CommanderOptions,\n type CommanderSlice,\n type CommandContext,\n type CommandDispatch,\n type CommandFn,\n type RevertFn,\n type UndoableCommand,\n type UndoEntry,\n} from \"./types.js\";\n\n// =============================================================================\n// Default Options\n// =============================================================================\n\nconst DEFAULT_OPTIONS: Required<CommanderOptions> = {\n maxUndoStackSize: 100,\n};\n\n// =============================================================================\n// Commander Implementation\n// =============================================================================\n\n/**\n * Creates a commander instance bound to a specific store type.\n *\n * @example\n * ```ts\n * // Create commander for your store type\n * const commander = createCommander<StoreState>();\n *\n * // Define commands\n * const addItem = commander.action(\n * Schema.Struct({ name: Schema.String }),\n * (ctx, params) => {\n * const { mimic } = ctx.getState();\n * mimic.document.transaction(root => {\n * // add item\n * });\n * }\n * );\n *\n * // Create store with middleware\n * const useStore = create(\n * commander.middleware(\n * mimic(document, (set, get) => ({\n * // your state\n * }))\n * )\n * );\n * ```\n */\nexport function createCommander<TStore extends object>(\n options: CommanderOptions = {}\n): Commander<TStore & CommanderSlice> {\n const { maxUndoStackSize } = { ...DEFAULT_OPTIONS, ...options };\n\n // Track the store API once middleware is applied\n let _storeApi: StoreApi<TStore & CommanderSlice> | null = null;\n\n /**\n * Creates the dispatch function for use within command handlers.\n */\n const createDispatch = (): CommandDispatch<TStore & CommanderSlice> => {\n return <TParams, TReturn>(\n command: Command<TStore & CommanderSlice, TParams, TReturn>\n ) => {\n return (params: TParams): TReturn => {\n if (!_storeApi) {\n throw new Error(\n \"Commander: Store not initialized. Make sure to use the commander middleware.\"\n );\n }\n\n // Create context for the command\n const ctx: CommandContext<TStore & CommanderSlice> = {\n getState: () => _storeApi!.getState(),\n setState: (partial) => _storeApi!.setState(partial as any),\n dispatch: createDispatch(),\n };\n\n // Execute the command\n const result = command.fn(ctx, params);\n\n // If it's an undoable command, add to undo stack\n if (isUndoableCommand(command)) {\n const entry: UndoEntry<TParams, TReturn> = {\n command,\n params,\n result,\n timestamp: Date.now(),\n };\n\n _storeApi.setState((state: TStore & CommanderSlice) => {\n const { undoStack, redoStack } = state._commander;\n\n // Add to undo stack, respecting max size\n const newUndoStack = [...undoStack, entry].slice(-maxUndoStackSize);\n\n // Clear redo stack when a new command is executed\n return {\n ...state,\n _commander: {\n undoStack: newUndoStack,\n redoStack: [],\n },\n };\n });\n }\n\n return result;\n };\n };\n };\n\n /**\n * Create a regular command (no undo support).\n */\n function action<TParams, TReturn = void>(\n fn: CommandFn<TStore & CommanderSlice, TParams, TReturn>\n ): Command<TStore & CommanderSlice, TParams, TReturn> {\n return {\n [COMMAND_SYMBOL]: true,\n fn,\n };\n }\n\n /**\n * Create an undoable command with undo/redo support.\n */\n function undoableAction<TParams, TReturn>(\n fn: CommandFn<TStore & CommanderSlice, TParams, TReturn>,\n revert: RevertFn<TStore & CommanderSlice, TParams, TReturn>\n ): UndoableCommand<TStore & CommanderSlice, TParams, TReturn> {\n return {\n [COMMAND_SYMBOL]: true,\n [UNDOABLE_COMMAND_SYMBOL]: true,\n fn,\n revert,\n };\n }\n\n /**\n * Zustand middleware that adds commander functionality.\n */\n const middleware = <T extends object>(\n config: (\n set: StoreApi<T & CommanderSlice>[\"setState\"],\n get: StoreApi<T & CommanderSlice>[\"getState\"],\n api: StoreApi<T & CommanderSlice>\n ) => T\n ) => {\n return (\n set: StoreApi<T & CommanderSlice>[\"setState\"],\n get: StoreApi<T & CommanderSlice>[\"getState\"],\n api: StoreApi<T & CommanderSlice>\n ): T & CommanderSlice => {\n // Store the API reference for dispatch\n _storeApi = api as unknown as StoreApi<TStore & CommanderSlice>;\n\n // Get user's state\n const userState = config(set, get, api);\n\n // Add commander slice\n return {\n ...userState,\n _commander: {\n undoStack: [],\n redoStack: [],\n },\n };\n };\n };\n\n return {\n action,\n undoableAction,\n middleware: middleware as Commander<TStore & CommanderSlice>[\"middleware\"],\n };\n}\n\n// =============================================================================\n// Undo/Redo Functions\n// =============================================================================\n\n/**\n * Perform an undo operation on the store.\n * Returns true if an undo was performed, false if undo stack was empty.\n */\nexport function performUndo<TStore extends CommanderSlice>(\n storeApi: StoreApi<TStore>\n): boolean {\n const state = storeApi.getState();\n const { undoStack, redoStack } = state._commander;\n\n // Pop the last entry from undo stack\n const entry = undoStack[undoStack.length - 1];\n if (!entry) {\n return false;\n }\n\n const newUndoStack = undoStack.slice(0, -1);\n\n // Create context for the revert function\n const ctx: CommandContext<TStore> = {\n getState: () => storeApi.getState(),\n setState: (partial) => storeApi.setState(partial as any),\n dispatch: createDispatchForUndo(storeApi),\n };\n\n // Execute the revert function\n entry.command.revert(ctx, entry.params, entry.result);\n\n // Move entry to redo stack\n storeApi.setState((state: TStore) => ({\n ...state,\n _commander: {\n undoStack: newUndoStack,\n redoStack: [...redoStack, entry],\n },\n }));\n\n return true;\n}\n\n/**\n * Perform a redo operation on the store.\n * Returns true if a redo was performed, false if redo stack was empty.\n */\nexport function performRedo<TStore extends CommanderSlice>(\n storeApi: StoreApi<TStore>\n): boolean {\n const state = storeApi.getState();\n const { undoStack, redoStack } = state._commander;\n\n // Pop the last entry from redo stack\n const entry = redoStack[redoStack.length - 1];\n if (!entry) {\n return false;\n }\n\n const newRedoStack = redoStack.slice(0, -1);\n\n // Create context for re-executing the command\n const ctx: CommandContext<TStore> = {\n getState: () => storeApi.getState(),\n setState: (partial) => storeApi.setState(partial as any),\n dispatch: createDispatchForUndo(storeApi),\n };\n\n // Re-execute the command\n const result = entry.command.fn(ctx, entry.params);\n\n // Create new entry with potentially new result\n const newEntry: UndoEntry = {\n command: entry.command,\n params: entry.params,\n result,\n timestamp: Date.now(),\n };\n\n // Move entry back to undo stack\n storeApi.setState((state: TStore) => ({\n ...state,\n _commander: {\n undoStack: [...undoStack, newEntry],\n redoStack: newRedoStack,\n },\n }));\n\n return true;\n}\n\n/**\n * Creates a dispatch function for use during undo/redo operations.\n * This dispatch does NOT add to undo stack (to avoid infinite loops).\n */\nfunction createDispatchForUndo<TStore>(\n storeApi: StoreApi<TStore>\n): CommandDispatch<TStore> {\n return <TParams, TReturn>(command: Command<TStore, TParams, TReturn>) => {\n return (params: TParams): TReturn => {\n const ctx: CommandContext<TStore> = {\n getState: () => storeApi.getState(),\n setState: (partial) => storeApi.setState(partial as any),\n dispatch: createDispatchForUndo(storeApi),\n };\n\n // Execute without adding to undo stack\n return command.fn(ctx, params);\n };\n };\n}\n\n/**\n * Clear the undo and redo stacks.\n */\nexport function clearUndoHistory<TStore extends CommanderSlice>(\n storeApi: StoreApi<TStore>\n): void {\n storeApi.setState((state: TStore) => ({\n ...state,\n _commander: {\n undoStack: [],\n redoStack: [],\n },\n }));\n}\n\n"],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ const require_objectSpread2 = require('../_virtual/_@oxc-project_runtime@0.103.0/helpers/objectSpread2.cjs');
2
+ const require_types = require('./types.cjs');
3
+ const require_commander = require('./commander.cjs');
4
+ let react = require("react");
5
+ let zustand = require("zustand");
6
+
7
+ //#region src/zustand-commander/hooks.ts
8
+ /**
9
+ * @voidhash/mimic-react/zustand-commander
10
+ *
11
+ * React hooks for zustand-commander.
12
+ *
13
+ * @since 0.0.1
14
+ */
15
+ /**
16
+ * Creates a dispatch function for commands.
17
+ * This is for use outside of React components (e.g., in command handlers).
18
+ */
19
+ function createDispatchFromApi(storeApi, maxUndoStackSize = 100) {
20
+ const dispatch = (command) => {
21
+ return (params) => {
22
+ const ctx = {
23
+ getState: () => storeApi.getState(),
24
+ setState: (partial) => storeApi.setState(partial),
25
+ dispatch
26
+ };
27
+ const result = command.fn(ctx, params);
28
+ if (require_types.isUndoableCommand(command)) storeApi.setState((state) => {
29
+ const { undoStack } = state._commander;
30
+ const newUndoStack = [...undoStack, {
31
+ command,
32
+ params,
33
+ result,
34
+ timestamp: Date.now()
35
+ }].slice(-maxUndoStackSize);
36
+ return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, state), {}, { _commander: {
37
+ undoStack: newUndoStack,
38
+ redoStack: []
39
+ } });
40
+ });
41
+ return result;
42
+ };
43
+ };
44
+ return dispatch;
45
+ }
46
+ /**
47
+ * React hook to get a dispatch function for commands.
48
+ * The dispatch function executes commands and manages undo/redo state.
49
+ *
50
+ * @example
51
+ * ```tsx
52
+ * const dispatch = useCommander(useStore);
53
+ *
54
+ * const handleClick = () => {
55
+ * dispatch(addCard)({ columnId: "col-1", title: "New Card" });
56
+ * };
57
+ * ```
58
+ */
59
+ function useCommander(store) {
60
+ const storeApi = (0, react.useMemo)(() => {
61
+ return store;
62
+ }, [store]);
63
+ return (0, react.useMemo)(() => createDispatchFromApi(storeApi), [storeApi]);
64
+ }
65
+ /**
66
+ * React hook for undo/redo functionality.
67
+ * Provides state (canUndo, canRedo) and actions (undo, redo, clear).
68
+ *
69
+ * @example
70
+ * ```tsx
71
+ * const { canUndo, canRedo, undo, redo } = useUndoRedo(useStore);
72
+ *
73
+ * return (
74
+ * <>
75
+ * <button onClick={undo} disabled={!canUndo}>Undo</button>
76
+ * <button onClick={redo} disabled={!canRedo}>Redo</button>
77
+ * </>
78
+ * );
79
+ * ```
80
+ */
81
+ function useUndoRedo(store) {
82
+ const storeApi = (0, react.useMemo)(() => {
83
+ return store;
84
+ }, [store]);
85
+ const commanderState = (0, zustand.useStore)(store, (state) => state._commander);
86
+ return {
87
+ canUndo: commanderState.undoStack.length > 0,
88
+ canRedo: commanderState.redoStack.length > 0,
89
+ undoCount: commanderState.undoStack.length,
90
+ redoCount: commanderState.redoStack.length,
91
+ undo: (0, react.useCallback)(() => {
92
+ return require_commander.performUndo(storeApi);
93
+ }, [storeApi]),
94
+ redo: (0, react.useCallback)(() => {
95
+ return require_commander.performRedo(storeApi);
96
+ }, [storeApi]),
97
+ clear: (0, react.useCallback)(() => {
98
+ require_commander.clearUndoHistory(storeApi);
99
+ }, [storeApi])
100
+ };
101
+ }
102
+ /**
103
+ * React hook that adds keyboard shortcuts for undo/redo.
104
+ * Listens for Ctrl/Cmd+Z (undo) and Ctrl/Cmd+Shift+Z or Ctrl+Y (redo).
105
+ *
106
+ * @example
107
+ * ```tsx
108
+ * // In your app component
109
+ * useUndoRedoKeyboard(useStore);
110
+ * ```
111
+ */
112
+ function useUndoRedoKeyboard(store, options = {}) {
113
+ const { enableUndo = true, enableRedo = true } = options;
114
+ const storeApi = (0, react.useMemo)(() => {
115
+ return store;
116
+ }, [store]);
117
+ (0, react.useEffect)(() => {
118
+ if (typeof window === "undefined") return;
119
+ const handleKeyDown = (event) => {
120
+ if (!(navigator.platform.toUpperCase().indexOf("MAC") >= 0 ? event.metaKey : event.ctrlKey)) return;
121
+ if (enableUndo && event.key === "z" && !event.shiftKey) {
122
+ event.preventDefault();
123
+ require_commander.performUndo(storeApi);
124
+ return;
125
+ }
126
+ if (enableRedo) {
127
+ if (event.key === "z" && event.shiftKey || event.key === "y") {
128
+ event.preventDefault();
129
+ require_commander.performRedo(storeApi);
130
+ }
131
+ }
132
+ };
133
+ window.addEventListener("keydown", handleKeyDown);
134
+ return () => window.removeEventListener("keydown", handleKeyDown);
135
+ }, [
136
+ storeApi,
137
+ enableUndo,
138
+ enableRedo
139
+ ]);
140
+ }
141
+
142
+ //#endregion
143
+ exports.useCommander = useCommander;
144
+ exports.useUndoRedo = useUndoRedo;
145
+ exports.useUndoRedoKeyboard = useUndoRedoKeyboard;