@voidhash/mimic-react 1.0.0-beta.13 → 1.0.0-beta.15
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/.turbo/turbo-build.log +36 -36
- package/dist/zustand/middleware.d.cts +1 -1
- package/dist/zustand/middleware.d.mts +1 -1
- package/dist/zustand/types.d.cts +1 -1
- package/dist/zustand/types.d.mts +1 -1
- package/dist/zustand/useDraft.cjs +14 -11
- package/dist/zustand/useDraft.d.cts +6 -5
- package/dist/zustand/useDraft.d.cts.map +1 -1
- package/dist/zustand/useDraft.d.mts +6 -5
- package/dist/zustand/useDraft.d.mts.map +1 -1
- package/dist/zustand/useDraft.mjs +14 -11
- package/dist/zustand/useDraft.mjs.map +1 -1
- package/dist/zustand-commander/commander.cjs +59 -22
- package/dist/zustand-commander/commander.d.cts +16 -6
- package/dist/zustand-commander/commander.d.cts.map +1 -1
- package/dist/zustand-commander/commander.d.mts +16 -6
- package/dist/zustand-commander/commander.d.mts.map +1 -1
- package/dist/zustand-commander/commander.mjs +57 -22
- package/dist/zustand-commander/commander.mjs.map +1 -1
- package/dist/zustand-commander/hooks.cjs +18 -4
- package/dist/zustand-commander/hooks.d.cts +2 -1
- package/dist/zustand-commander/hooks.d.cts.map +1 -1
- package/dist/zustand-commander/hooks.d.mts +2 -1
- package/dist/zustand-commander/hooks.d.mts.map +1 -1
- package/dist/zustand-commander/hooks.mjs +18 -4
- package/dist/zustand-commander/hooks.mjs.map +1 -1
- package/dist/zustand-commander/index.cjs +2 -0
- package/dist/zustand-commander/index.d.cts +2 -2
- package/dist/zustand-commander/index.d.mts +2 -2
- package/dist/zustand-commander/index.mjs +2 -2
- package/dist/zustand-commander/types.d.cts +23 -14
- package/dist/zustand-commander/types.d.cts.map +1 -1
- package/dist/zustand-commander/types.d.mts +23 -14
- package/dist/zustand-commander/types.d.mts.map +1 -1
- package/dist/zustand-commander/types.mjs.map +1 -1
- package/package.json +3 -3
- package/src/zustand/useDraft.ts +15 -19
- package/src/zustand-commander/commander.ts +107 -21
- package/src/zustand-commander/hooks.ts +38 -12
- package/src/zustand-commander/index.ts +2 -0
- package/src/zustand-commander/types.ts +34 -24
- package/tests/zustand-commander/commander.test.ts +321 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { StoreApi, UseBoundStore } from "zustand";
|
|
2
|
+
import { Primitive } from "@voidhash/mimic";
|
|
3
|
+
import { ClientDocument } from "@voidhash/mimic/client";
|
|
2
4
|
|
|
3
5
|
//#region src/zustand-commander/types.d.ts
|
|
4
6
|
|
|
@@ -14,7 +16,7 @@ declare const UNDOABLE_COMMAND_SYMBOL: unique symbol;
|
|
|
14
16
|
* Context provided to command functions.
|
|
15
17
|
* Gives access to store state and dispatch capabilities.
|
|
16
18
|
*/
|
|
17
|
-
interface CommandContext<TStore> {
|
|
19
|
+
interface CommandContext<TStore, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> {
|
|
18
20
|
/**
|
|
19
21
|
* Get the current store state.
|
|
20
22
|
*/
|
|
@@ -30,32 +32,37 @@ interface CommandContext<TStore> {
|
|
|
30
32
|
* @example
|
|
31
33
|
* dispatch(otherCommand)({ param: "value" });
|
|
32
34
|
*/
|
|
33
|
-
readonly dispatch: CommandDispatch<TStore>;
|
|
35
|
+
readonly dispatch: CommandDispatch<TStore, TSchema>;
|
|
36
|
+
/**
|
|
37
|
+
* Run a transaction on the document.
|
|
38
|
+
* Routes to the active draft if one is linked, otherwise to the document directly.
|
|
39
|
+
*/
|
|
40
|
+
readonly transaction: (fn: (root: Primitive.InferProxy<TSchema>) => void) => void;
|
|
34
41
|
}
|
|
35
42
|
/**
|
|
36
43
|
* The function signature for a command handler.
|
|
37
44
|
*/
|
|
38
|
-
type CommandFn<TStore, TParams, TReturn> = (ctx: CommandContext<TStore>, params: TParams) => TReturn;
|
|
45
|
+
type CommandFn<TStore, TParams, TReturn, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> = (ctx: CommandContext<TStore, TSchema>, params: TParams) => TReturn;
|
|
39
46
|
/**
|
|
40
47
|
* The function signature for an undoable command's revert handler.
|
|
41
48
|
* Receives the original params and the result from the forward execution.
|
|
42
49
|
*/
|
|
43
|
-
type RevertFn<TStore, TParams, TReturn> = (ctx: CommandContext<TStore>, params: TParams, result: TReturn) => void;
|
|
50
|
+
type RevertFn<TStore, TParams, TReturn, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> = (ctx: CommandContext<TStore, TSchema>, params: TParams, result: TReturn) => void;
|
|
44
51
|
/**
|
|
45
52
|
* A command that can be dispatched to modify store state.
|
|
46
53
|
* Regular commands do not support undo/redo.
|
|
47
54
|
*/
|
|
48
|
-
interface Command<TStore, TParams, TReturn> {
|
|
55
|
+
interface Command<TStore, TParams, TReturn, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> {
|
|
49
56
|
readonly [COMMAND_SYMBOL]: true;
|
|
50
|
-
readonly fn: CommandFn<TStore, TParams, TReturn>;
|
|
57
|
+
readonly fn: CommandFn<TStore, TParams, TReturn, TSchema>;
|
|
51
58
|
}
|
|
52
59
|
/**
|
|
53
60
|
* An undoable command that supports undo/redo.
|
|
54
61
|
* Must provide a revert function that knows how to undo the change.
|
|
55
62
|
*/
|
|
56
|
-
interface UndoableCommand<TStore, TParams, TReturn> extends Command<TStore, TParams, TReturn> {
|
|
63
|
+
interface UndoableCommand<TStore, TParams, TReturn, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> extends Command<TStore, TParams, TReturn, TSchema> {
|
|
57
64
|
readonly [UNDOABLE_COMMAND_SYMBOL]: true;
|
|
58
|
-
readonly revert: RevertFn<TStore, TParams, TReturn>;
|
|
65
|
+
readonly revert: RevertFn<TStore, TParams, TReturn, TSchema>;
|
|
59
66
|
}
|
|
60
67
|
/**
|
|
61
68
|
* Any command type (regular or undoable).
|
|
@@ -72,7 +79,7 @@ type AnyUndoableCommand = UndoableCommand<any, any, any>;
|
|
|
72
79
|
* @example
|
|
73
80
|
* const result = dispatch(myCommand)({ param: "value" });
|
|
74
81
|
*/
|
|
75
|
-
type CommandDispatch<TStore> = <TParams, TReturn>(command: Command<TStore, TParams, TReturn>) => (params: TParams) => TReturn;
|
|
82
|
+
type CommandDispatch<TStore, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> = <TParams, TReturn>(command: Command<TStore, TParams, TReturn, TSchema>) => (params: TParams) => TReturn;
|
|
76
83
|
/**
|
|
77
84
|
* An entry in the undo/redo stack.
|
|
78
85
|
* Contains all information needed to revert or redo a command.
|
|
@@ -96,6 +103,8 @@ interface CommanderSlice {
|
|
|
96
103
|
readonly undoStack: ReadonlyArray<UndoEntry>;
|
|
97
104
|
/** Stack of commands that can be redone */
|
|
98
105
|
readonly redoStack: ReadonlyArray<UndoEntry>;
|
|
106
|
+
/** Active draft handle, if any. When set, transactions route through the draft and undo is disabled. */
|
|
107
|
+
readonly activeDraft: ClientDocument.DraftHandle<any> | null;
|
|
99
108
|
};
|
|
100
109
|
}
|
|
101
110
|
/**
|
|
@@ -112,7 +121,7 @@ interface CommanderOptions {
|
|
|
112
121
|
* A commander instance bound to a specific store type.
|
|
113
122
|
* Used to create commands and the middleware.
|
|
114
123
|
*/
|
|
115
|
-
interface Commander<TStore> {
|
|
124
|
+
interface Commander<TStore, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> {
|
|
116
125
|
/**
|
|
117
126
|
* Create a regular command (no undo support).
|
|
118
127
|
*
|
|
@@ -130,8 +139,8 @@ interface Commander<TStore> {
|
|
|
130
139
|
* });
|
|
131
140
|
*/
|
|
132
141
|
readonly action: {
|
|
133
|
-
<TParams, TReturn = void>(fn: CommandFn<TStore, TParams, TReturn>): Command<TStore, TParams, TReturn>;
|
|
134
|
-
<TReturn = void>(fn: CommandFn<TStore, void, TReturn>): Command<TStore, void, TReturn>;
|
|
142
|
+
<TParams, TReturn = void>(fn: CommandFn<TStore, TParams, TReturn, TSchema>): Command<TStore, TParams, TReturn, TSchema>;
|
|
143
|
+
<TReturn = void>(fn: CommandFn<TStore, void, TReturn, TSchema>): Command<TStore, void, TReturn, TSchema>;
|
|
135
144
|
};
|
|
136
145
|
/**
|
|
137
146
|
* Create an undoable command with undo/redo support.
|
|
@@ -151,8 +160,8 @@ interface Commander<TStore> {
|
|
|
151
160
|
* );
|
|
152
161
|
*/
|
|
153
162
|
readonly undoableAction: {
|
|
154
|
-
<TParams, TReturn>(fn: CommandFn<TStore, TParams, TReturn>, revert: RevertFn<TStore, TParams, TReturn>): UndoableCommand<TStore, TParams, TReturn>;
|
|
155
|
-
<TReturn>(fn: CommandFn<TStore, void, TReturn>, revert: RevertFn<TStore, void, TReturn>): UndoableCommand<TStore, void, TReturn>;
|
|
163
|
+
<TParams, TReturn>(fn: CommandFn<TStore, TParams, TReturn, TSchema>, revert: RevertFn<TStore, TParams, TReturn, TSchema>): UndoableCommand<TStore, TParams, TReturn, TSchema>;
|
|
164
|
+
<TReturn>(fn: CommandFn<TStore, void, TReturn, TSchema>, revert: RevertFn<TStore, void, TReturn, TSchema>): UndoableCommand<TStore, void, TReturn, TSchema>;
|
|
156
165
|
};
|
|
157
166
|
/**
|
|
158
167
|
* Zustand middleware that adds commander functionality.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.cts","names":[],"sources":["../../src/zustand-commander/types.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.cts","names":[],"sources":["../../src/zustand-commander/types.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAsDqC,cAnCxB,cAmCwB,EAAA,OAAA,MAAA;;;;AAMD,cApCvB,uBAoCiC,EAAA,OAAA,MAAA;;AAU9C;;;AACsB,UAnCL,cAmCK,CAAA,MAAA,EAAA,gBAnCkC,SAAA,CAAU,YAmC5C,GAnC2D,SAAA,CAAU,YAmCrE,CAAA,CAAA;EAAQ;;;EAEzB,SAAA,QAAA,EAAA,GAAA,GAjCsB,MAiCtB;EAAO;AAMZ;;EAAwF,SAAU,QAAA,EAAA,CAAA,OAAA,EAlCnE,OAkCmE,CAlC3D,MAkC2D,CAAA,EAAA,GAAA,IAAA;EAC5E;;;;;;AAatB;EAAmE,SAAU,QAAA,EAvCxD,eAuCwD,CAvCxC,MAuCwC,EAvChC,OAuCgC,CAAA;EAAe;;;;EAElD,SAAA,WAAA,EAAA,CAAA,EAAA,EAAA,CAAA,IAAA,EAnCN,SAAA,CAAU,UAmCJ,CAnCe,OAmCf,CAAA,EAAA,GAAA,IAAA,EAAA,GAAA,IAAA;;;;AAO1C;AAA2E,KAhC/D,SAgCyE,CAAA,MAAA,EAAA,OAAA,EAAA,OAAA,EAAA,gBAhCrB,SAAA,CAAU,YAgCW,GAhCI,SAAA,CAAU,YAgCd,CAAA,GAAA,CAAA,GAAA,EA/B9E,cA+B8E,CA/B/D,MA+B+D,EA/BvD,OA+BuD,CAAA,EAAA,MAAA,EA9B3E,OA8B2E,EAAA,GA7BhF,OA6BgF;;;;;AACzC,KAxBhC,QAwBgC,CAAA,MAAA,EAAA,OAAA,EAAA,OAAA,EAAA,gBAxBmB,SAAA,CAAU,YAwB7B,GAxB4C,SAAA,CAAU,YAwBtD,CAAA,GAAA,CAAA,GAAA,EAvBrC,cAuBqC,CAvBtB,MAuBsB,EAvBd,OAuBc,CAAA,EAAA,MAAA,EAtBlC,OAsBkC,EAAA,MAAA,EArBlC,OAqBkC,EAAA,GAAA,IAAA;;;;;AAEU,UAZrC,OAYqC,CAAA,MAAA,EAAA,OAAA,EAAA,OAAA,EAAA,gBAZa,SAAA,CAAU,YAYvB,GAZsC,SAAA,CAAU,YAYhD,CAAA,CAAA;EAAnC,UAXP,cAAA,CAWO,EAAA,IAAA;EAFT,SAAA,EAAA,EARK,SAQL,CARe,MAQf,EARuB,OAQvB,EARgC,OAQhC,EARyC,OAQzC,CAAA;;AAQV;AAKA;AAaA;;AAA6E,UA3B5D,eA2BsE,CAAA,MAAA,EAAA,OAAA,EAAA,OAAA,EAAA,gBA3BZ,SAAA,CAAU,YA2BE,GA3Ba,SAAA,CAAU,YA2BvB,CAAA,SA1B7E,OA0B6E,CA1BrE,MA0BqE,EA1B7D,OA0B6D,EA1BpD,OA0BoD,EA1B3C,OA0B2C,CAAA,CAAA;EACpE,UA1BP,uBAAA,CA0BO,EAAA,IAAA;EAAQ,SAAA,MAAA,EAzBR,QAyBQ,CAzBC,MAyBD,EAzBS,OAyBT,EAzBkB,OAyBlB,EAzB2B,OAyB3B,CAAA;;;;;AACD,KApBd,UAAA,GAAa,OAoBC,CAAA,GAAA,EAAA,GAAA,EAAA,GAAA,CAAA;;AAU1B;;AAImB,KA7BP,kBAAA,GAAqB,eA6Bd,CAAA,GAAA,EAAA,GAAA,EAAA,GAAA,CAAA;;;AAUnB;;;;;AAO0B,KAjCd,eAiC6B,CAAA,MAAA,EAAA,gBAjCW,SAAA,CAAU,YAiCrB,GAjCoC,SAAA,CAAU,YAiC9C,CAAA,GAAA,CAAA,OAAA,EAAA,OAAA,CAAA,CAAA,OAAA,EAhC9B,OAgC8B,CAhCtB,MAgCsB,EAhCd,OAgCc,EAhCL,OAgCK,EAhCI,OAgCJ,CAAA,EAAA,GAAA,CAAA,MAAA,EA/B3B,OA+B2B,EAAA,GA/Bf,OA+Be;;AAWzC;AAYA;;AAA4E,UA5C3D,SA4CqE,CAAA,UAAA,OAAA,EAAA,UAAA,OAAA,CAAA,CAAA;EAoBlE;EAAQ,SAAA,OAAA,EA9DR,kBA8DQ;EAAS;EAAS,SAAA,MAAA,EA5D3B,OA4D2B;EAApC;EACK,SAAA,MAAA,EA3DI,OA2DJ;EAAQ;EAAS,SAAA,SAAA,EAAA,MAAA;;;;;AAIW,UAvD1B,cAAA,CAuD0B;EAAjC,SAAA,UAAA,EAAA;IACK;IAAc,SAAA,SAAA,EArDL,aAqDK,CArDS,SAqDT,CAAA;IAAS;IAA/B,SAAA,SAAA,EAnDiB,aAmDjB,CAnD+B,SAmD/B,CAAA;IAuBa;IAAQ,SAAA,WAAA,EAxEF,cAAA,CAAe,WAwEb,CAAA,GAAA,CAAA,GAAA,IAAA;EAAS,CAAA;;;;;AACG,UA9DvB,gBAAA,CA8DuB;EAAS;;;;EACT,SAAA,gBAAA,CAAA,EAAA,MAAA;;;;;;AAI9B,UAvDO,SAuDP,CAAA,MAAA,EAAA,gBAvDyC,SAAA,CAAU,YAuDnD,GAvDkE,SAAA,CAAU,YAuD5E,CAAA,CAAA;EACa;;;;;;;;;;;AAiBvB;;;;;EAGsB,SAAA,MAAA,EAAA;IAAb,CAAA,OAAA,EAAA,UAAA,IAAA,CAAA,CAAA,EAAA,EAxDC,SAwDD,CAxDW,MAwDX,EAxDmB,OAwDnB,EAxD4B,OAwD5B,EAxDqC,OAwDrC,CAAA,CAAA,EAvDF,OAuDE,CAvDM,MAuDN,EAvDc,OAuDd,EAvDuB,OAuDvB,EAvDgC,OAuDhC,CAAA;IACS,CAAA,UAAA,IAAA,CAAA,CAAA,EAAA,EApDR,SAoDQ,CApDE,MAoDF,EAAA,IAAA,EApDgB,OAoDhB,EApDyB,OAoDzB,CAAA,CAAA,EAnDX,OAmDW,CAnDH,MAmDG,EAAA,IAAA,EAnDW,OAmDX,EAnDoB,OAmDpB,CAAA;EAAI,CAAA;EAAb;;;;;;;;;;;;;;AAeT;AAKA;AAOA;EASgB,SAAA,cAAS,EAA2B;IAYpC,CAAA,OAAA,EAAA,OAAiB,CAAA,CAAA,EAAA,EA5EvB,SA8EE,CA9EQ,MA8ER,EA9EgB,OA8EE,EA9EO,OA8EP,EA9EgB,OA8EhB,CAAA,EAAA,MAAA,EA7EhB,QA6EgB,CA7EP,MA6EO,EA7EC,OA6ED,EA7EU,OA6EV,EA7EmB,OA6EnB,CAAA,CAAA,EA5EvB,eA4EuB,CA5EP,MA4EO,EA5EC,OA4ED,EA5EU,OA4EV,EA5EmB,OA4EnB,CAAA;IAelB,CAAA,OAAA,CAAA,CAAA,EAAY,EAvFd,SAuFc,CAvFJ,MAuFI,EAAA,IAAA,EAvFU,OAuFV,EAvFmB,OAuFnB,CAAA,EAAA,MAAA,EAtFV,QAsFU,CAtFD,MAsFC,EAAA,IAAA,EAtFa,OAsFb,EAtFsB,OAsFtB,CAAA,CAAA,EArFjB,eAqFiB,CArFD,MAqFC,EAAA,IAAA,EArFa,OAqFb,EArFsB,OAqFtB,CAAA;EAAW,CAAA;EACjC;;;;EAGyB,SAAA,UAAA,EAlFJ,mBAkFI,CAlFgB,MAkFhB,CAAA;;;;;;;KAzEf,gEAEH,SAAS,IAAI,kCACb,SAAS,IAAI,kCACb,SAAS,IAAI,oBACf,YAEA,SAAS,IAAI,kCACb,SAAS,IAAI,kCACb,SAAS,IAAI,oBACf,IAAI;;;;KASG,mBAAmB,UAAU;;;;KAK7B,mBAAmB,UAAU;;;;KAO7B,kBAAkB,UAAU;;;;iBASxB,SAAA,2BAAoC;;;;iBAYpC,iBAAA,2BAEJ;;;;KAeA,uBAAuB,eAAe,cAChD,yBAGE,eAAe"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { StoreApi, UseBoundStore } from "zustand";
|
|
2
|
+
import { Primitive } from "@voidhash/mimic";
|
|
3
|
+
import { ClientDocument } from "@voidhash/mimic/client";
|
|
2
4
|
|
|
3
5
|
//#region src/zustand-commander/types.d.ts
|
|
4
6
|
|
|
@@ -14,7 +16,7 @@ declare const UNDOABLE_COMMAND_SYMBOL: unique symbol;
|
|
|
14
16
|
* Context provided to command functions.
|
|
15
17
|
* Gives access to store state and dispatch capabilities.
|
|
16
18
|
*/
|
|
17
|
-
interface CommandContext<TStore> {
|
|
19
|
+
interface CommandContext<TStore, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> {
|
|
18
20
|
/**
|
|
19
21
|
* Get the current store state.
|
|
20
22
|
*/
|
|
@@ -30,32 +32,37 @@ interface CommandContext<TStore> {
|
|
|
30
32
|
* @example
|
|
31
33
|
* dispatch(otherCommand)({ param: "value" });
|
|
32
34
|
*/
|
|
33
|
-
readonly dispatch: CommandDispatch<TStore>;
|
|
35
|
+
readonly dispatch: CommandDispatch<TStore, TSchema>;
|
|
36
|
+
/**
|
|
37
|
+
* Run a transaction on the document.
|
|
38
|
+
* Routes to the active draft if one is linked, otherwise to the document directly.
|
|
39
|
+
*/
|
|
40
|
+
readonly transaction: (fn: (root: Primitive.InferProxy<TSchema>) => void) => void;
|
|
34
41
|
}
|
|
35
42
|
/**
|
|
36
43
|
* The function signature for a command handler.
|
|
37
44
|
*/
|
|
38
|
-
type CommandFn<TStore, TParams, TReturn> = (ctx: CommandContext<TStore>, params: TParams) => TReturn;
|
|
45
|
+
type CommandFn<TStore, TParams, TReturn, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> = (ctx: CommandContext<TStore, TSchema>, params: TParams) => TReturn;
|
|
39
46
|
/**
|
|
40
47
|
* The function signature for an undoable command's revert handler.
|
|
41
48
|
* Receives the original params and the result from the forward execution.
|
|
42
49
|
*/
|
|
43
|
-
type RevertFn<TStore, TParams, TReturn> = (ctx: CommandContext<TStore>, params: TParams, result: TReturn) => void;
|
|
50
|
+
type RevertFn<TStore, TParams, TReturn, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> = (ctx: CommandContext<TStore, TSchema>, params: TParams, result: TReturn) => void;
|
|
44
51
|
/**
|
|
45
52
|
* A command that can be dispatched to modify store state.
|
|
46
53
|
* Regular commands do not support undo/redo.
|
|
47
54
|
*/
|
|
48
|
-
interface Command<TStore, TParams, TReturn> {
|
|
55
|
+
interface Command<TStore, TParams, TReturn, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> {
|
|
49
56
|
readonly [COMMAND_SYMBOL]: true;
|
|
50
|
-
readonly fn: CommandFn<TStore, TParams, TReturn>;
|
|
57
|
+
readonly fn: CommandFn<TStore, TParams, TReturn, TSchema>;
|
|
51
58
|
}
|
|
52
59
|
/**
|
|
53
60
|
* An undoable command that supports undo/redo.
|
|
54
61
|
* Must provide a revert function that knows how to undo the change.
|
|
55
62
|
*/
|
|
56
|
-
interface UndoableCommand<TStore, TParams, TReturn> extends Command<TStore, TParams, TReturn> {
|
|
63
|
+
interface UndoableCommand<TStore, TParams, TReturn, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> extends Command<TStore, TParams, TReturn, TSchema> {
|
|
57
64
|
readonly [UNDOABLE_COMMAND_SYMBOL]: true;
|
|
58
|
-
readonly revert: RevertFn<TStore, TParams, TReturn>;
|
|
65
|
+
readonly revert: RevertFn<TStore, TParams, TReturn, TSchema>;
|
|
59
66
|
}
|
|
60
67
|
/**
|
|
61
68
|
* Any command type (regular or undoable).
|
|
@@ -72,7 +79,7 @@ type AnyUndoableCommand = UndoableCommand<any, any, any>;
|
|
|
72
79
|
* @example
|
|
73
80
|
* const result = dispatch(myCommand)({ param: "value" });
|
|
74
81
|
*/
|
|
75
|
-
type CommandDispatch<TStore> = <TParams, TReturn>(command: Command<TStore, TParams, TReturn>) => (params: TParams) => TReturn;
|
|
82
|
+
type CommandDispatch<TStore, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> = <TParams, TReturn>(command: Command<TStore, TParams, TReturn, TSchema>) => (params: TParams) => TReturn;
|
|
76
83
|
/**
|
|
77
84
|
* An entry in the undo/redo stack.
|
|
78
85
|
* Contains all information needed to revert or redo a command.
|
|
@@ -96,6 +103,8 @@ interface CommanderSlice {
|
|
|
96
103
|
readonly undoStack: ReadonlyArray<UndoEntry>;
|
|
97
104
|
/** Stack of commands that can be redone */
|
|
98
105
|
readonly redoStack: ReadonlyArray<UndoEntry>;
|
|
106
|
+
/** Active draft handle, if any. When set, transactions route through the draft and undo is disabled. */
|
|
107
|
+
readonly activeDraft: ClientDocument.DraftHandle<any> | null;
|
|
99
108
|
};
|
|
100
109
|
}
|
|
101
110
|
/**
|
|
@@ -112,7 +121,7 @@ interface CommanderOptions {
|
|
|
112
121
|
* A commander instance bound to a specific store type.
|
|
113
122
|
* Used to create commands and the middleware.
|
|
114
123
|
*/
|
|
115
|
-
interface Commander<TStore> {
|
|
124
|
+
interface Commander<TStore, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> {
|
|
116
125
|
/**
|
|
117
126
|
* Create a regular command (no undo support).
|
|
118
127
|
*
|
|
@@ -130,8 +139,8 @@ interface Commander<TStore> {
|
|
|
130
139
|
* });
|
|
131
140
|
*/
|
|
132
141
|
readonly action: {
|
|
133
|
-
<TParams, TReturn = void>(fn: CommandFn<TStore, TParams, TReturn>): Command<TStore, TParams, TReturn>;
|
|
134
|
-
<TReturn = void>(fn: CommandFn<TStore, void, TReturn>): Command<TStore, void, TReturn>;
|
|
142
|
+
<TParams, TReturn = void>(fn: CommandFn<TStore, TParams, TReturn, TSchema>): Command<TStore, TParams, TReturn, TSchema>;
|
|
143
|
+
<TReturn = void>(fn: CommandFn<TStore, void, TReturn, TSchema>): Command<TStore, void, TReturn, TSchema>;
|
|
135
144
|
};
|
|
136
145
|
/**
|
|
137
146
|
* Create an undoable command with undo/redo support.
|
|
@@ -151,8 +160,8 @@ interface Commander<TStore> {
|
|
|
151
160
|
* );
|
|
152
161
|
*/
|
|
153
162
|
readonly undoableAction: {
|
|
154
|
-
<TParams, TReturn>(fn: CommandFn<TStore, TParams, TReturn>, revert: RevertFn<TStore, TParams, TReturn>): UndoableCommand<TStore, TParams, TReturn>;
|
|
155
|
-
<TReturn>(fn: CommandFn<TStore, void, TReturn>, revert: RevertFn<TStore, void, TReturn>): UndoableCommand<TStore, void, TReturn>;
|
|
163
|
+
<TParams, TReturn>(fn: CommandFn<TStore, TParams, TReturn, TSchema>, revert: RevertFn<TStore, TParams, TReturn, TSchema>): UndoableCommand<TStore, TParams, TReturn, TSchema>;
|
|
164
|
+
<TReturn>(fn: CommandFn<TStore, void, TReturn, TSchema>, revert: RevertFn<TStore, void, TReturn, TSchema>): UndoableCommand<TStore, void, TReturn, TSchema>;
|
|
156
165
|
};
|
|
157
166
|
/**
|
|
158
167
|
* Zustand middleware that adds commander functionality.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../../src/zustand-commander/types.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../../src/zustand-commander/types.ts"],"sourcesContent":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.mjs","names":[],"sources":["../../src/zustand-commander/types.ts"],"sourcesContent":["/**\n * @voidhash/mimic-react/zustand-commander\n *\n * Type definitions for the zustand-commander package.\n *\n * @since 0.0.1\n */\n\nimport type { StoreApi, UseBoundStore } from \"zustand\";\n\n// =============================================================================\n// Command Symbol & Type Guard\n// =============================================================================\n\n/**\n * Symbol used to identify Command objects at runtime.\n */\nexport const COMMAND_SYMBOL = Symbol.for(\"zustand-commander/command\");\n\n/**\n * Symbol used to identify UndoableCommand objects at runtime.\n */\nexport const UNDOABLE_COMMAND_SYMBOL = Symbol.for(\n \"zustand-commander/undoable-command\"\n);\n\n// =============================================================================\n// Command Context\n// =============================================================================\n\n/**\n * Context provided to command functions.\n * Gives access to store state and dispatch capabilities.\n */\nexport interface CommandContext<TStore> {\n /**\n * Get the current store state.\n */\n readonly getState: () => TStore;\n\n /**\n * Set partial store state (for local/browser state updates).\n */\n readonly setState: (partial: Partial<TStore>) => void;\n\n /**\n * Dispatch another command.\n * Returns the result of the dispatched command.\n *\n * @example\n * dispatch(otherCommand)({ param: \"value\" });\n */\n readonly dispatch: CommandDispatch<TStore>;\n}\n\n// =============================================================================\n// Command Function Types\n// =============================================================================\n\n/**\n * The function signature for a command handler.\n */\nexport type CommandFn<TStore, TParams, TReturn> = (\n ctx: CommandContext<TStore>,\n params: TParams\n) => TReturn;\n\n/**\n * The function signature for an undoable command's revert handler.\n * Receives the original params and the result from the forward execution.\n */\nexport type RevertFn<TStore, TParams, TReturn> = (\n ctx: CommandContext<TStore>,\n params: TParams,\n result: TReturn\n) => void;\n\n// =============================================================================\n// Command Types\n// =============================================================================\n\n/**\n * A command that can be dispatched to modify store state.\n * Regular commands do not support undo/redo.\n */\nexport interface Command<TStore, TParams, TReturn> {\n readonly [COMMAND_SYMBOL]: true;\n readonly fn: CommandFn<TStore, TParams, TReturn>;\n}\n\n/**\n * An undoable command that supports undo/redo.\n * Must provide a revert function that knows how to undo the change.\n */\nexport interface UndoableCommand<TStore, TParams, TReturn>\n extends Command<TStore, TParams, TReturn> {\n readonly [UNDOABLE_COMMAND_SYMBOL]: true;\n readonly revert: RevertFn<TStore, TParams, TReturn>;\n}\n\n/**\n * Any command type (regular or undoable).\n */\nexport type AnyCommand = Command<any, any, any>;\n\n/**\n * Any undoable command type.\n */\nexport type AnyUndoableCommand = UndoableCommand<any, any, any>;\n\n// =============================================================================\n// Command Dispatch\n// =============================================================================\n\n/**\n * Dispatch function that accepts commands and returns a function to call with params.\n * Returns the result of the command execution.\n *\n * @example\n * const result = dispatch(myCommand)({ param: \"value\" });\n */\nexport type CommandDispatch<TStore> = <TParams, TReturn>(\n command: Command<TStore, TParams, TReturn>\n) => (params: TParams) => TReturn;\n\n// =============================================================================\n// Undo/Redo Stack Types\n// =============================================================================\n\n/**\n * An entry in the undo/redo stack.\n * Contains all information needed to revert or redo a command.\n */\nexport interface UndoEntry<TParams = unknown, TReturn = unknown> {\n /** The undoable command that was executed */\n readonly command: AnyUndoableCommand;\n /** The parameters that were passed to the command */\n readonly params: TParams;\n /** The result returned by the command (passed to revert) */\n readonly result: TReturn;\n /** Timestamp when the command was executed */\n readonly timestamp: number;\n}\n\n/**\n * State slice for undo/redo functionality.\n */\nexport interface CommanderSlice {\n readonly _commander: {\n /** Stack of commands that can be undone */\n readonly undoStack: ReadonlyArray<UndoEntry>;\n /** Stack of commands that can be redone */\n readonly redoStack: ReadonlyArray<UndoEntry>;\n };\n}\n\n// =============================================================================\n// Commander Types\n// =============================================================================\n\n/**\n * Options for creating a commander.\n */\nexport interface CommanderOptions {\n /**\n * Maximum number of undo entries to keep.\n * @default 100\n */\n readonly maxUndoStackSize?: number;\n}\n\n/**\n * A commander instance bound to a specific store type.\n * Used to create commands and the middleware.\n */\nexport interface Commander<TStore> {\n /**\n * Create a regular command (no undo support).\n *\n * @example\n * // With params\n * const addItem = commander.action<{ name: string }>(\n * (ctx, params) => {\n * // modify state using params.name\n * }\n * );\n *\n * // Without params\n * const clearAll = commander.action((ctx) => {\n * // modify state\n * });\n */\n readonly action: {\n // With params (explicit type parameter)\n <TParams, TReturn = void>(\n fn: CommandFn<TStore, TParams, TReturn>\n ): Command<TStore, TParams, TReturn>;\n\n // Without params (void) - inferred when no type param provided\n <TReturn = void>(\n fn: CommandFn<TStore, void, TReturn>\n ): Command<TStore, void, TReturn>;\n };\n\n /**\n * Create an undoable command with undo/redo support.\n * The revert function is called when undoing the command.\n *\n * @example\n * const moveItem = commander.undoableAction<{ id: string; toIndex: number }, { fromIndex: number }>(\n * (ctx, params) => {\n * const fromIndex = // get current index\n * // perform move\n * return { fromIndex }; // return data needed for revert\n * },\n * (ctx, params, result) => {\n * // revert: move back to original position\n * ctx.dispatch(moveItem)({ id: params.id, toIndex: result.fromIndex });\n * }\n * );\n */\n readonly undoableAction: {\n // With params (explicit type parameter)\n <TParams, TReturn>(\n fn: CommandFn<TStore, TParams, TReturn>,\n revert: RevertFn<TStore, TParams, TReturn>\n ): UndoableCommand<TStore, TParams, TReturn>;\n\n // Without params (void)\n <TReturn>(\n fn: CommandFn<TStore, void, TReturn>,\n revert: RevertFn<TStore, void, TReturn>\n ): UndoableCommand<TStore, void, TReturn>;\n };\n\n /**\n * Zustand middleware that adds commander functionality.\n * Adds undo/redo stacks to the store state.\n */\n readonly middleware: CommanderMiddleware<TStore>;\n}\n\n/**\n * Type for the commander middleware.\n * Note: TStore is intentionally unused here to match the Commander interface signature.\n * The middleware is generic over T (the inner store type) and adds CommanderSlice.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport type CommanderMiddleware<_TStore> = <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 set: StoreApi<T & CommanderSlice>[\"setState\"],\n get: StoreApi<T & CommanderSlice>[\"getState\"],\n api: StoreApi<T & CommanderSlice>\n) => T & CommanderSlice;\n\n// =============================================================================\n// Type Helpers\n// =============================================================================\n\n/**\n * Extract the params type from a command.\n */\nexport type CommandParams<T> = T extends Command<any, infer P, any> ? P : never;\n\n/**\n * Extract the return type from a command.\n */\nexport type CommandReturn<T> = T extends Command<any, any, infer R>\n ? R\n : undefined;\n\n/**\n * Extract the store type from a command.\n */\nexport type CommandStore<T> = T extends Command<infer S, any, any> ? S : never;\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * Type guard to check if a value is a Command.\n */\nexport function isCommand(value: unknown): value is AnyCommand {\n return (\n typeof value === \"object\" &&\n value !== null &&\n COMMAND_SYMBOL in value &&\n value[COMMAND_SYMBOL] === true\n );\n}\n\n/**\n * Type guard to check if a command is undoable.\n */\nexport function isUndoableCommand(\n value: unknown\n): value is AnyUndoableCommand {\n return (\n isCommand(value) &&\n UNDOABLE_COMMAND_SYMBOL in value &&\n value[UNDOABLE_COMMAND_SYMBOL] === true\n );\n}\n\n// =============================================================================\n// Store Type Helper\n// =============================================================================\n\n/**\n * Helper type to extract the state type from a zustand store.\n */\nexport type ExtractState<TStore> = TStore extends UseBoundStore<\n StoreApi<infer S>\n>\n ? S\n : TStore extends StoreApi<infer S>\n ? S\n : never;\n\n"],"mappings":";;;;AAiBA,MAAa,iBAAiB,OAAO,IAAI,4BAA4B;;;;AAKrE,MAAa,0BAA0B,OAAO,IAC5C,qCACD;;;;AAwQD,SAAgB,UAAU,OAAqC;AAC7D,QACE,OAAO,UAAU,YACjB,UAAU,QACV,kBAAkB,SAClB,MAAM,oBAAoB;;;;;AAO9B,SAAgB,kBACd,OAC6B;AAC7B,QACE,UAAU,MAAM,IAChB,2BAA2B,SAC3B,MAAM,6BAA6B"}
|
|
1
|
+
{"version":3,"file":"types.mjs","names":[],"sources":["../../src/zustand-commander/types.ts"],"sourcesContent":["/**\n * @voidhash/mimic-react/zustand-commander\n *\n * Type definitions for the zustand-commander package.\n *\n * @since 0.0.1\n */\n\nimport type { StoreApi, UseBoundStore } from \"zustand\";\nimport type { Primitive } from \"@voidhash/mimic\";\nimport type { ClientDocument } from \"@voidhash/mimic/client\";\n\n// =============================================================================\n// Command Symbol & Type Guard\n// =============================================================================\n\n/**\n * Symbol used to identify Command objects at runtime.\n */\nexport const COMMAND_SYMBOL = Symbol.for(\"zustand-commander/command\");\n\n/**\n * Symbol used to identify UndoableCommand objects at runtime.\n */\nexport const UNDOABLE_COMMAND_SYMBOL = Symbol.for(\n \"zustand-commander/undoable-command\"\n);\n\n// =============================================================================\n// Command Context\n// =============================================================================\n\n/**\n * Context provided to command functions.\n * Gives access to store state and dispatch capabilities.\n */\nexport interface CommandContext<TStore, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> {\n /**\n * Get the current store state.\n */\n readonly getState: () => TStore;\n\n /**\n * Set partial store state (for local/browser state updates).\n */\n readonly setState: (partial: Partial<TStore>) => void;\n\n /**\n * Dispatch another command.\n * Returns the result of the dispatched command.\n *\n * @example\n * dispatch(otherCommand)({ param: \"value\" });\n */\n readonly dispatch: CommandDispatch<TStore, TSchema>;\n\n /**\n * Run a transaction on the document.\n * Routes to the active draft if one is linked, otherwise to the document directly.\n */\n readonly transaction: (fn: (root: Primitive.InferProxy<TSchema>) => void) => void;\n}\n\n// =============================================================================\n// Command Function Types\n// =============================================================================\n\n/**\n * The function signature for a command handler.\n */\nexport type CommandFn<TStore, TParams, TReturn, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> = (\n ctx: CommandContext<TStore, TSchema>,\n params: TParams\n) => TReturn;\n\n/**\n * The function signature for an undoable command's revert handler.\n * Receives the original params and the result from the forward execution.\n */\nexport type RevertFn<TStore, TParams, TReturn, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> = (\n ctx: CommandContext<TStore, TSchema>,\n params: TParams,\n result: TReturn\n) => void;\n\n// =============================================================================\n// Command Types\n// =============================================================================\n\n/**\n * A command that can be dispatched to modify store state.\n * Regular commands do not support undo/redo.\n */\nexport interface Command<TStore, TParams, TReturn, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> {\n readonly [COMMAND_SYMBOL]: true;\n readonly fn: CommandFn<TStore, TParams, TReturn, TSchema>;\n}\n\n/**\n * An undoable command that supports undo/redo.\n * Must provide a revert function that knows how to undo the change.\n */\nexport interface UndoableCommand<TStore, TParams, TReturn, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive>\n extends Command<TStore, TParams, TReturn, TSchema> {\n readonly [UNDOABLE_COMMAND_SYMBOL]: true;\n readonly revert: RevertFn<TStore, TParams, TReturn, TSchema>;\n}\n\n/**\n * Any command type (regular or undoable).\n */\nexport type AnyCommand = Command<any, any, any>;\n\n/**\n * Any undoable command type.\n */\nexport type AnyUndoableCommand = UndoableCommand<any, any, any>;\n\n// =============================================================================\n// Command Dispatch\n// =============================================================================\n\n/**\n * Dispatch function that accepts commands and returns a function to call with params.\n * Returns the result of the command execution.\n *\n * @example\n * const result = dispatch(myCommand)({ param: \"value\" });\n */\nexport type CommandDispatch<TStore, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> = <TParams, TReturn>(\n command: Command<TStore, TParams, TReturn, TSchema>\n) => (params: TParams) => TReturn;\n\n// =============================================================================\n// Undo/Redo Stack Types\n// =============================================================================\n\n/**\n * An entry in the undo/redo stack.\n * Contains all information needed to revert or redo a command.\n */\nexport interface UndoEntry<TParams = unknown, TReturn = unknown> {\n /** The undoable command that was executed */\n readonly command: AnyUndoableCommand;\n /** The parameters that were passed to the command */\n readonly params: TParams;\n /** The result returned by the command (passed to revert) */\n readonly result: TReturn;\n /** Timestamp when the command was executed */\n readonly timestamp: number;\n}\n\n/**\n * State slice for undo/redo functionality.\n */\nexport interface CommanderSlice {\n readonly _commander: {\n /** Stack of commands that can be undone */\n readonly undoStack: ReadonlyArray<UndoEntry>;\n /** Stack of commands that can be redone */\n readonly redoStack: ReadonlyArray<UndoEntry>;\n /** Active draft handle, if any. When set, transactions route through the draft and undo is disabled. */\n readonly activeDraft: ClientDocument.DraftHandle<any> | null;\n };\n}\n\n// =============================================================================\n// Commander Types\n// =============================================================================\n\n/**\n * Options for creating a commander.\n */\nexport interface CommanderOptions {\n /**\n * Maximum number of undo entries to keep.\n * @default 100\n */\n readonly maxUndoStackSize?: number;\n}\n\n/**\n * A commander instance bound to a specific store type.\n * Used to create commands and the middleware.\n */\nexport interface Commander<TStore, TSchema extends Primitive.AnyPrimitive = Primitive.AnyPrimitive> {\n /**\n * Create a regular command (no undo support).\n *\n * @example\n * // With params\n * const addItem = commander.action<{ name: string }>(\n * (ctx, params) => {\n * // modify state using params.name\n * }\n * );\n *\n * // Without params\n * const clearAll = commander.action((ctx) => {\n * // modify state\n * });\n */\n readonly action: {\n // With params (explicit type parameter)\n <TParams, TReturn = void>(\n fn: CommandFn<TStore, TParams, TReturn, TSchema>\n ): Command<TStore, TParams, TReturn, TSchema>;\n\n // Without params (void) - inferred when no type param provided\n <TReturn = void>(\n fn: CommandFn<TStore, void, TReturn, TSchema>\n ): Command<TStore, void, TReturn, TSchema>;\n };\n\n /**\n * Create an undoable command with undo/redo support.\n * The revert function is called when undoing the command.\n *\n * @example\n * const moveItem = commander.undoableAction<{ id: string; toIndex: number }, { fromIndex: number }>(\n * (ctx, params) => {\n * const fromIndex = // get current index\n * // perform move\n * return { fromIndex }; // return data needed for revert\n * },\n * (ctx, params, result) => {\n * // revert: move back to original position\n * ctx.dispatch(moveItem)({ id: params.id, toIndex: result.fromIndex });\n * }\n * );\n */\n readonly undoableAction: {\n // With params (explicit type parameter)\n <TParams, TReturn>(\n fn: CommandFn<TStore, TParams, TReturn, TSchema>,\n revert: RevertFn<TStore, TParams, TReturn, TSchema>\n ): UndoableCommand<TStore, TParams, TReturn, TSchema>;\n\n // Without params (void)\n <TReturn>(\n fn: CommandFn<TStore, void, TReturn, TSchema>,\n revert: RevertFn<TStore, void, TReturn, TSchema>\n ): UndoableCommand<TStore, void, TReturn, TSchema>;\n };\n\n /**\n * Zustand middleware that adds commander functionality.\n * Adds undo/redo stacks to the store state.\n */\n readonly middleware: CommanderMiddleware<TStore>;\n}\n\n/**\n * Type for the commander middleware.\n * Note: TStore is intentionally unused here to match the Commander interface signature.\n * The middleware is generic over T (the inner store type) and adds CommanderSlice.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport type CommanderMiddleware<_TStore> = <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 set: StoreApi<T & CommanderSlice>[\"setState\"],\n get: StoreApi<T & CommanderSlice>[\"getState\"],\n api: StoreApi<T & CommanderSlice>\n) => T & CommanderSlice;\n\n// =============================================================================\n// Type Helpers\n// =============================================================================\n\n/**\n * Extract the params type from a command.\n */\nexport type CommandParams<T> = T extends Command<any, infer P, any> ? P : never;\n\n/**\n * Extract the return type from a command.\n */\nexport type CommandReturn<T> = T extends Command<any, any, infer R>\n ? R\n : undefined;\n\n/**\n * Extract the store type from a command.\n */\nexport type CommandStore<T> = T extends Command<infer S, any, any> ? S : never;\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * Type guard to check if a value is a Command.\n */\nexport function isCommand(value: unknown): value is AnyCommand {\n return (\n typeof value === \"object\" &&\n value !== null &&\n COMMAND_SYMBOL in value &&\n value[COMMAND_SYMBOL] === true\n );\n}\n\n/**\n * Type guard to check if a command is undoable.\n */\nexport function isUndoableCommand(\n value: unknown\n): value is AnyUndoableCommand {\n return (\n isCommand(value) &&\n UNDOABLE_COMMAND_SYMBOL in value &&\n value[UNDOABLE_COMMAND_SYMBOL] === true\n );\n}\n\n// =============================================================================\n// Store Type Helper\n// =============================================================================\n\n/**\n * Helper type to extract the state type from a zustand store.\n */\nexport type ExtractState<TStore> = TStore extends UseBoundStore<\n StoreApi<infer S>\n>\n ? S\n : TStore extends StoreApi<infer S>\n ? S\n : never;\n\n"],"mappings":";;;;AAmBA,MAAa,iBAAiB,OAAO,IAAI,4BAA4B;;;;AAKrE,MAAa,0BAA0B,OAAO,IAC5C,qCACD;;;;AAgRD,SAAgB,UAAU,OAAqC;AAC7D,QACE,OAAO,UAAU,YACjB,UAAU,QACV,kBAAkB,SAClB,MAAM,oBAAoB;;;;;AAO9B,SAAgB,kBACd,OAC6B;AAC7B,QACE,UAAU,MAAM,IAChB,2BAA2B,SAC3B,MAAM,6BAA6B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voidhash/mimic-react",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.15",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -37,12 +37,12 @@
|
|
|
37
37
|
"typescript": "5.8.3",
|
|
38
38
|
"vite-tsconfig-paths": "^5.1.4",
|
|
39
39
|
"vitest": "^3.2.4",
|
|
40
|
-
"@voidhash/tsconfig": "1.0.0-beta.
|
|
40
|
+
"@voidhash/tsconfig": "1.0.0-beta.15"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"effect": "^3.16.0",
|
|
44
44
|
"react": "^18.0.0 || ^19.0.0",
|
|
45
|
-
"@voidhash/mimic": "1.0.0-beta.
|
|
45
|
+
"@voidhash/mimic": "1.0.0-beta.15"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "tsdown",
|
package/src/zustand/useDraft.ts
CHANGED
|
@@ -4,6 +4,8 @@ import type { StoreApi } from "zustand";
|
|
|
4
4
|
import type { ClientDocument } from "@voidhash/mimic/client";
|
|
5
5
|
import type { Primitive } from "@voidhash/mimic";
|
|
6
6
|
import type { MimicSlice } from "./types";
|
|
7
|
+
import type { CommanderSlice } from "../zustand-commander/types";
|
|
8
|
+
import { setActiveDraft, clearActiveDraft } from "../zustand-commander/commander";
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Return type of the useDraft hook.
|
|
@@ -17,21 +19,21 @@ export interface UseDraftReturn<TSchema extends Primitive.AnyPrimitive> {
|
|
|
17
19
|
readonly commit: () => void;
|
|
18
20
|
/** Discards the active draft. No-op if no draft is active. */
|
|
19
21
|
readonly discard: () => void;
|
|
20
|
-
/** Runs an update on the active draft. Throws if no draft is active. */
|
|
21
|
-
readonly update: (fn: (root: Primitive.InferProxy<TSchema>) => void) => void;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* React hook for managing a draft lifecycle with auto-cleanup on unmount.
|
|
26
|
+
* Links the draft to the commander so that `ctx.transaction()` routes through the draft
|
|
27
|
+
* and undo/redo is disabled while the draft is active.
|
|
26
28
|
*
|
|
27
|
-
* @param store - The zustand store containing the mimic slice
|
|
29
|
+
* @param store - The zustand store containing the mimic slice and commander slice
|
|
28
30
|
* @returns Draft control methods
|
|
29
31
|
*/
|
|
30
32
|
export const useDraft = <
|
|
31
33
|
TSchema extends Primitive.AnyPrimitive,
|
|
32
34
|
TPresence extends import("@voidhash/mimic").Presence.AnyPresence | undefined = undefined,
|
|
33
35
|
>(
|
|
34
|
-
store: StoreApi<MimicSlice<TSchema, TPresence
|
|
36
|
+
store: StoreApi<MimicSlice<TSchema, TPresence> & CommanderSlice>
|
|
35
37
|
): UseDraftReturn<TSchema> => {
|
|
36
38
|
const draftRef = useRef<ClientDocument.DraftHandle<TSchema> | null>(null);
|
|
37
39
|
// Use a counter to force re-renders when draft state changes
|
|
@@ -60,39 +62,34 @@ export const useDraft = <
|
|
|
60
62
|
throw new Error("A draft is already active. Commit or discard it first.");
|
|
61
63
|
}
|
|
62
64
|
const document = store.getState().mimic.document;
|
|
63
|
-
|
|
65
|
+
const draft = document.createDraft();
|
|
66
|
+
draftRef.current = draft;
|
|
67
|
+
setActiveDraft(store, draft);
|
|
64
68
|
bumpVersion();
|
|
65
69
|
}, [store, bumpVersion]);
|
|
66
70
|
|
|
67
71
|
const commit = useCallback(() => {
|
|
68
72
|
if (draftRef.current === null) return;
|
|
73
|
+
clearActiveDraft(store);
|
|
69
74
|
draftRef.current.commit();
|
|
70
75
|
draftRef.current = null;
|
|
71
76
|
bumpVersion();
|
|
72
|
-
}, [bumpVersion]);
|
|
77
|
+
}, [store, bumpVersion]);
|
|
73
78
|
|
|
74
79
|
const discard = useCallback(() => {
|
|
75
80
|
if (draftRef.current === null) return;
|
|
81
|
+
clearActiveDraft(store);
|
|
76
82
|
draftRef.current.discard();
|
|
77
83
|
draftRef.current = null;
|
|
78
84
|
bumpVersion();
|
|
79
|
-
}, [bumpVersion]);
|
|
80
|
-
|
|
81
|
-
const update = useCallback(
|
|
82
|
-
(fn: (root: Primitive.InferProxy<TSchema>) => void) => {
|
|
83
|
-
if (draftRef.current === null) {
|
|
84
|
-
throw new Error("No active draft. Call begin() first.");
|
|
85
|
-
}
|
|
86
|
-
draftRef.current.update(fn);
|
|
87
|
-
},
|
|
88
|
-
[]
|
|
89
|
-
);
|
|
85
|
+
}, [store, bumpVersion]);
|
|
90
86
|
|
|
91
87
|
// Auto-discard on unmount
|
|
92
88
|
useEffect(() => {
|
|
93
89
|
return () => {
|
|
94
90
|
if (draftRef.current !== null) {
|
|
95
91
|
try {
|
|
92
|
+
clearActiveDraft(store);
|
|
96
93
|
draftRef.current.discard();
|
|
97
94
|
} catch {
|
|
98
95
|
// Draft may already be consumed
|
|
@@ -100,13 +97,12 @@ export const useDraft = <
|
|
|
100
97
|
draftRef.current = null;
|
|
101
98
|
}
|
|
102
99
|
};
|
|
103
|
-
}, []);
|
|
100
|
+
}, [store]);
|
|
104
101
|
|
|
105
102
|
return {
|
|
106
103
|
draft: draftRef.current,
|
|
107
104
|
begin,
|
|
108
105
|
commit,
|
|
109
106
|
discard,
|
|
110
|
-
update,
|
|
111
107
|
};
|
|
112
108
|
};
|