@encorejs/saaz 1.0.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.
- package/LICENSE +203 -0
- package/README.md +1 -0
- package/dist/back/BackMemoryAdapter.d.ts +18 -0
- package/dist/back/BackMemoryAdapter.d.ts.map +1 -0
- package/dist/back/BackMemoryAdapter.js +69 -0
- package/dist/back/BackStorage.d.ts +20 -0
- package/dist/back/BackStorage.d.ts.map +1 -0
- package/dist/back/BackStorage.js +22 -0
- package/dist/back/SaazBack.d.ts +60 -0
- package/dist/back/SaazBack.d.ts.map +1 -0
- package/dist/back/SaazBack.js +188 -0
- package/dist/front/FrontIdbAdapter.d.ts +15 -0
- package/dist/front/FrontIdbAdapter.d.ts.map +1 -0
- package/dist/front/FrontIdbAdapter.js +159 -0
- package/dist/front/FrontMemoryAdapter.d.ts +16 -0
- package/dist/front/FrontMemoryAdapter.d.ts.map +1 -0
- package/dist/front/FrontMemoryAdapter.js +156 -0
- package/dist/front/FrontStorage.d.ts +23 -0
- package/dist/front/FrontStorage.d.ts.map +1 -0
- package/dist/front/FrontStorage.js +85 -0
- package/dist/front/SaazFront.d.ts +113 -0
- package/dist/front/SaazFront.d.ts.map +1 -0
- package/dist/front/SaazFront.js +756 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9295 -0
- package/dist/index.js.map +7 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +166 -0
- package/dist/rogue.d.ts +63 -0
- package/dist/rogue.d.ts.map +1 -0
- package/dist/rogue.js +548 -0
- package/dist/rogue.test.d.ts +2 -0
- package/dist/rogue.test.d.ts.map +1 -0
- package/dist/rogue.test.js +248 -0
- package/dist/shared/GeneratorSpy.d.ts +4 -0
- package/dist/shared/GeneratorSpy.d.ts.map +1 -0
- package/dist/shared/GeneratorSpy.js +41 -0
- package/dist/shared/transactions.d.ts +4 -0
- package/dist/shared/transactions.d.ts.map +1 -0
- package/dist/shared/transactions.js +131 -0
- package/dist/shared/utils.d.ts +5 -0
- package/dist/shared/utils.d.ts.map +1 -0
- package/dist/shared/utils.js +21 -0
- package/dist/tsdoc-metadata.json +11 -0
- package/dist/types.d.ts +240 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +54 -0
package/dist/rogue.js
ADDED
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
import deepEqual from '@encorejs/utils/deepEqual';
|
|
2
|
+
import * as immer from 'immer';
|
|
3
|
+
import setDeep from 'lodash-es/set';
|
|
4
|
+
import memoizeFn from '@encorejs/utils/memoizeFn';
|
|
5
|
+
const NOT_DEFINED = {};
|
|
6
|
+
function isCell(v) {
|
|
7
|
+
if (typeof v !== 'object' || v === null)
|
|
8
|
+
return false;
|
|
9
|
+
const $type = v.$type;
|
|
10
|
+
if (!Array.isArray($type))
|
|
11
|
+
return false;
|
|
12
|
+
if ($type.length !== 2 && $type.length !== 1)
|
|
13
|
+
return false;
|
|
14
|
+
if (typeof $type[0] !== 'string')
|
|
15
|
+
return false;
|
|
16
|
+
const [type, branchName] = $type;
|
|
17
|
+
if (type === 'map' || type === 'boxed' || type === 'deleted')
|
|
18
|
+
return true;
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
export function makeDraft(base) {
|
|
22
|
+
if (!isPlainObject(base)) {
|
|
23
|
+
throw Error(`Base must be a plain object`);
|
|
24
|
+
}
|
|
25
|
+
base = isCell(base)
|
|
26
|
+
? base
|
|
27
|
+
: {
|
|
28
|
+
$type: ['map', 'base'],
|
|
29
|
+
$branches: { base: { $mapProps: base } },
|
|
30
|
+
};
|
|
31
|
+
const immerDraft = immer.createDraft(base);
|
|
32
|
+
const state = {
|
|
33
|
+
imo: immerDraft,
|
|
34
|
+
};
|
|
35
|
+
const draft = new Proxy(state, traps);
|
|
36
|
+
const finish = () => {
|
|
37
|
+
const cell = immer.finishDraft(immerDraft);
|
|
38
|
+
const forwardOps = compare(base, cell);
|
|
39
|
+
const backwardOps = compare(cell, base);
|
|
40
|
+
return [cell, forwardOps, backwardOps];
|
|
41
|
+
};
|
|
42
|
+
return [draft, finish];
|
|
43
|
+
}
|
|
44
|
+
export function change(base, fn) {
|
|
45
|
+
const [draft, finish] = makeDraft(base);
|
|
46
|
+
fn(draft);
|
|
47
|
+
return finish();
|
|
48
|
+
}
|
|
49
|
+
export function fromOps(base, ops) {
|
|
50
|
+
if (!isPlainObject(base)) {
|
|
51
|
+
throw Error(`Base must be a plain object`);
|
|
52
|
+
}
|
|
53
|
+
base = isCell(base)
|
|
54
|
+
? base
|
|
55
|
+
: {
|
|
56
|
+
$type: ['map', 'base'],
|
|
57
|
+
$branches: { base: { $mapProps: base } },
|
|
58
|
+
};
|
|
59
|
+
const immerDraft = immer.createDraft(base);
|
|
60
|
+
const state = {
|
|
61
|
+
imo: immerDraft,
|
|
62
|
+
};
|
|
63
|
+
for (const op of ops) {
|
|
64
|
+
const flatPath = op.path
|
|
65
|
+
.map(([branchName, mapProp]) => [
|
|
66
|
+
'$branches',
|
|
67
|
+
branchName,
|
|
68
|
+
'$mapProps',
|
|
69
|
+
mapProp,
|
|
70
|
+
])
|
|
71
|
+
.flat();
|
|
72
|
+
if (op.type === 'ChangeType') {
|
|
73
|
+
const [type, branchName] = op.value;
|
|
74
|
+
setDeep(immerDraft, [...flatPath, '$type'], [type, branchName]);
|
|
75
|
+
}
|
|
76
|
+
else if (op.type === 'SetBoxedValue') {
|
|
77
|
+
setDeep(immerDraft, [...flatPath, '$branches', op.branchName, '$boxedValue'], op.value);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
throw Error(`Unrecognized op type: ${op.type}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return [immer.finishDraft(immerDraft)];
|
|
84
|
+
}
|
|
85
|
+
function compare(before, after) {
|
|
86
|
+
const ops = [];
|
|
87
|
+
compareCell(before, after, [], ops);
|
|
88
|
+
return ops;
|
|
89
|
+
}
|
|
90
|
+
function compareCell(before, after, path, ops) {
|
|
91
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
92
|
+
if (before === after)
|
|
93
|
+
return;
|
|
94
|
+
if (!deepEqual(before === null || before === void 0 ? void 0 : before.$type, after.$type)) {
|
|
95
|
+
const beforeType = before
|
|
96
|
+
? [before.$type[0], (_a = before.$type[1]) !== null && _a !== void 0 ? _a : 'base']
|
|
97
|
+
: null;
|
|
98
|
+
const afterType = [after.$type[0], (_b = after.$type[1]) !== null && _b !== void 0 ? _b : 'base'];
|
|
99
|
+
if (!deepEqual(beforeType, afterType)) {
|
|
100
|
+
ops.push({
|
|
101
|
+
type: 'ChangeType',
|
|
102
|
+
path,
|
|
103
|
+
value: after.$type,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const [type, branchName] = [after.$type[0], (_c = after.$type[1]) !== null && _c !== void 0 ? _c : 'base'];
|
|
108
|
+
const afterBranch = (_d = after.$branches) === null || _d === void 0 ? void 0 : _d[branchName];
|
|
109
|
+
const beforeBranch = (_e = before === null || before === void 0 ? void 0 : before.$branches) === null || _e === void 0 ? void 0 : _e[branchName];
|
|
110
|
+
if (afterBranch === beforeBranch)
|
|
111
|
+
return;
|
|
112
|
+
if (!afterBranch)
|
|
113
|
+
return;
|
|
114
|
+
if (type === 'deleted')
|
|
115
|
+
return;
|
|
116
|
+
if (type === 'boxed') {
|
|
117
|
+
if (afterBranch.$boxedValue !== (beforeBranch === null || beforeBranch === void 0 ? void 0 : beforeBranch.$boxedValue)) {
|
|
118
|
+
ops.push({
|
|
119
|
+
type: 'SetBoxedValue',
|
|
120
|
+
path,
|
|
121
|
+
branchName,
|
|
122
|
+
value: afterBranch.$boxedValue,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (type === 'map') {
|
|
128
|
+
const beforeMapProps = (_f = beforeBranch === null || beforeBranch === void 0 ? void 0 : beforeBranch.$mapProps) !== null && _f !== void 0 ? _f : {};
|
|
129
|
+
const afterMapProps = (_g = afterBranch.$mapProps) !== null && _g !== void 0 ? _g : {};
|
|
130
|
+
const afterKeys = Object.keys(afterMapProps);
|
|
131
|
+
for (const prop of afterKeys) {
|
|
132
|
+
compareCell(Object.hasOwn(beforeMapProps, prop) ? beforeMapProps[prop] : undefined, afterMapProps[prop], [...path, [branchName, prop]], ops);
|
|
133
|
+
}
|
|
134
|
+
const beforeKeys = Object.keys(beforeMapProps);
|
|
135
|
+
for (const prop of beforeKeys) {
|
|
136
|
+
if (!Object.hasOwn(afterMapProps, prop)) {
|
|
137
|
+
ops.push({
|
|
138
|
+
type: 'ChangeType',
|
|
139
|
+
path: [...path, [branchName, prop]],
|
|
140
|
+
value: ['deleted', generateBranchName()],
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
throw Error(`Unrecognized type: ${type}`);
|
|
147
|
+
}
|
|
148
|
+
let _lastBranchName = 0;
|
|
149
|
+
const generateBranchName = () => {
|
|
150
|
+
_lastBranchName++;
|
|
151
|
+
return _lastBranchName.toString();
|
|
152
|
+
};
|
|
153
|
+
const traps = {
|
|
154
|
+
get(state, prop) {
|
|
155
|
+
var _a, _b, _c, _d, _e, _f;
|
|
156
|
+
if (prop === DRAFT_STATE)
|
|
157
|
+
return state;
|
|
158
|
+
if (typeof prop !== 'string')
|
|
159
|
+
return undefined;
|
|
160
|
+
const imo = state.imo;
|
|
161
|
+
const type = imo.$type[0];
|
|
162
|
+
const branchName = (_a = imo.$type[1]) !== null && _a !== void 0 ? _a : 'base';
|
|
163
|
+
if (type === 'deleted')
|
|
164
|
+
throw new Error(`This value is marked as deleted and cannot be accessed`);
|
|
165
|
+
if (type === 'boxed')
|
|
166
|
+
throw new Error(`Implement getting inside a boxed value`);
|
|
167
|
+
if (type === 'map') {
|
|
168
|
+
const mapProps = (_c = (_b = imo.$branches) === null || _b === void 0 ? void 0 : _b[branchName]) === null || _c === void 0 ? void 0 : _c.$mapProps;
|
|
169
|
+
if (!mapProps)
|
|
170
|
+
return undefined;
|
|
171
|
+
if (Object.hasOwn(mapProps, prop)) {
|
|
172
|
+
const value = mapProps[prop];
|
|
173
|
+
if (!isCell(value)) {
|
|
174
|
+
throw Error(`mapProps[${prop}] is not an ahistoric cell. this is a bug.`);
|
|
175
|
+
}
|
|
176
|
+
if (value.$type[0] === 'deleted')
|
|
177
|
+
return undefined;
|
|
178
|
+
if (value.$type[0] === 'boxed') {
|
|
179
|
+
const boxedValue = (_f = (_d = value.$branches) === null || _d === void 0 ? void 0 : _d[(_e = value.$type[1]) !== null && _e !== void 0 ? _e : 'base']) === null || _f === void 0 ? void 0 : _f.$boxedValue;
|
|
180
|
+
if (isPlainObject(boxedValue)) {
|
|
181
|
+
throw Error(`Implement getting a mapProp that is a boxed object`);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
return boxedValue;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else if (value.$type[0] === 'map') {
|
|
188
|
+
const subState = {
|
|
189
|
+
imo: value,
|
|
190
|
+
parent: state,
|
|
191
|
+
};
|
|
192
|
+
return new Proxy(subState, traps);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
throw new Error(`Unrecognized type: ${type}`);
|
|
200
|
+
},
|
|
201
|
+
set(state, prop, _value) {
|
|
202
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
203
|
+
var _m, _o;
|
|
204
|
+
if (prop === DRAFT_STATE)
|
|
205
|
+
throw Error(`Unallowed`);
|
|
206
|
+
if (typeof prop !== 'string')
|
|
207
|
+
throw Error(`Non-string props are not allowed`);
|
|
208
|
+
const value = valueType(_value);
|
|
209
|
+
const imo = state.imo;
|
|
210
|
+
const cellType = imo.$type[0];
|
|
211
|
+
const branchName = (_a = imo.$type[1]) !== null && _a !== void 0 ? _a : 'base';
|
|
212
|
+
// setting self.a=value, when self is deleted
|
|
213
|
+
if (cellType === 'deleted')
|
|
214
|
+
throw new Error(`This value is marked as deleted and cannot be changed`);
|
|
215
|
+
// setting self.a=value, when self is a boxed value
|
|
216
|
+
if (cellType === 'boxed')
|
|
217
|
+
throw new Error(`Implement setting inside a boxed value`);
|
|
218
|
+
// setting self.a=value when self is a map
|
|
219
|
+
if (cellType === 'map') {
|
|
220
|
+
let branches = imo.$branches;
|
|
221
|
+
if (!branches) {
|
|
222
|
+
branches = {};
|
|
223
|
+
imo.$branches = branches;
|
|
224
|
+
}
|
|
225
|
+
let branch = branches[branchName];
|
|
226
|
+
if (!branch) {
|
|
227
|
+
branch = {};
|
|
228
|
+
branches[branchName] = branch;
|
|
229
|
+
}
|
|
230
|
+
let mapProps = branch.$mapProps;
|
|
231
|
+
if (!mapProps) {
|
|
232
|
+
mapProps = {};
|
|
233
|
+
branch.$mapProps = mapProps;
|
|
234
|
+
}
|
|
235
|
+
// setting self.a=value when self.a is defined
|
|
236
|
+
if (Object.hasOwn(mapProps, prop)) {
|
|
237
|
+
if (!isCell(mapProps[prop]))
|
|
238
|
+
throw Error(`mapProps[${prop}] is not an ahistoric cell. this is a bug.`);
|
|
239
|
+
const currentPropCell = mapProps[prop];
|
|
240
|
+
// setting self.a={}
|
|
241
|
+
if (value.type === 'map') {
|
|
242
|
+
let currentBranch;
|
|
243
|
+
// setting self.a={} when self.a is not a map
|
|
244
|
+
if (currentPropCell.$type[0] !== 'map') {
|
|
245
|
+
// we're switching from a non-map to a map, which means if a map was previously set, it was
|
|
246
|
+
// already deleted/overridden to be a boxed value, and the current user hasn't _seen_ the previous
|
|
247
|
+
// map yet. So we should generate a new branchName for the new map.
|
|
248
|
+
const newBranchName = generateBranchName();
|
|
249
|
+
currentPropCell.$type = ['map', newBranchName];
|
|
250
|
+
(_b = currentPropCell.$branches) !== null && _b !== void 0 ? _b : (currentPropCell.$branches = {});
|
|
251
|
+
const newBranch = { $mapProps: {} };
|
|
252
|
+
currentPropCell.$branches[newBranchName] = newBranch;
|
|
253
|
+
currentBranch = newBranch;
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
(_c = currentPropCell.$branches) !== null && _c !== void 0 ? _c : (currentPropCell.$branches = {});
|
|
257
|
+
(_e = (_m = currentPropCell.$branches)[_o = (_d = currentPropCell.$type[1]) !== null && _d !== void 0 ? _d : 'base']) !== null && _e !== void 0 ? _e : (_m[_o] = {});
|
|
258
|
+
currentBranch =
|
|
259
|
+
currentPropCell.$branches[(_f = currentPropCell.$type[1]) !== null && _f !== void 0 ? _f : 'base'];
|
|
260
|
+
}
|
|
261
|
+
const subState = {
|
|
262
|
+
imo: currentPropCell,
|
|
263
|
+
parent: state,
|
|
264
|
+
};
|
|
265
|
+
const proxy = new Proxy(subState, traps);
|
|
266
|
+
const existingProps = Object.keys(proxy);
|
|
267
|
+
// let's delete existing props that are not in the new value
|
|
268
|
+
for (const key of existingProps) {
|
|
269
|
+
if (!Object.hasOwn(value.value, key)) {
|
|
270
|
+
delete proxy[key];
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
for (const key of Object.keys(value.value)) {
|
|
274
|
+
;
|
|
275
|
+
proxy[key] = value.value[key];
|
|
276
|
+
}
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
else if (value.type === 'boxed') {
|
|
280
|
+
if (currentPropCell.$type[0] === 'boxed') {
|
|
281
|
+
(_g = currentPropCell.$branches) !== null && _g !== void 0 ? _g : (currentPropCell.$branches = {});
|
|
282
|
+
const branches = currentPropCell.$branches;
|
|
283
|
+
const branchName = (_h = currentPropCell.$type[1]) !== null && _h !== void 0 ? _h : 'base';
|
|
284
|
+
(_j = branches[branchName]) !== null && _j !== void 0 ? _j : (branches[branchName] = {});
|
|
285
|
+
const branch = branches[branchName];
|
|
286
|
+
branch.$boxedValue = value.value;
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
const branchName = generateBranchName();
|
|
291
|
+
currentPropCell.$type = ['boxed', branchName];
|
|
292
|
+
(_k = currentPropCell.$branches) !== null && _k !== void 0 ? _k : (currentPropCell.$branches = {});
|
|
293
|
+
const branches = currentPropCell.$branches;
|
|
294
|
+
(_l = branches[branchName]) !== null && _l !== void 0 ? _l : (branches[branchName] = {});
|
|
295
|
+
const branch = branches[branchName];
|
|
296
|
+
branch.$boxedValue = value.value;
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
throw new Error(`Unrecognized type: ${currentPropCell.$type[0]}`);
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
if (value.type === 'boxed') {
|
|
304
|
+
mapProps[prop] = {
|
|
305
|
+
$type: ['boxed', 'base'],
|
|
306
|
+
$branches: {
|
|
307
|
+
base: {
|
|
308
|
+
$boxedValue: value.value,
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
};
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
314
|
+
else if (value.type === 'map') {
|
|
315
|
+
mapProps[prop] = {
|
|
316
|
+
$type: ['map', 'base'],
|
|
317
|
+
};
|
|
318
|
+
const subState = {
|
|
319
|
+
imo: mapProps[prop],
|
|
320
|
+
parent: state,
|
|
321
|
+
};
|
|
322
|
+
const proxy = new Proxy(subState, traps);
|
|
323
|
+
for (const [k, v] of Object.entries(value.value)) {
|
|
324
|
+
;
|
|
325
|
+
proxy[k] = v;
|
|
326
|
+
}
|
|
327
|
+
return true;
|
|
328
|
+
}
|
|
329
|
+
throw Error(`Unrecognized type: ${value.type}`);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
throw new Error(`Unrecognized type: ${cellType}`);
|
|
333
|
+
},
|
|
334
|
+
has(state, prop) {
|
|
335
|
+
throw Error(`Implement has()`);
|
|
336
|
+
},
|
|
337
|
+
ownKeys(state) {
|
|
338
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
339
|
+
const type = state.imo.$type[0];
|
|
340
|
+
if (type === 'boxed') {
|
|
341
|
+
const value = (_c = (_a = state.imo.$branches) === null || _a === void 0 ? void 0 : _a[(_b = state.imo.$type[1]) !== null && _b !== void 0 ? _b : 'base']) === null || _c === void 0 ? void 0 : _c.$boxedValue;
|
|
342
|
+
if (isPlainObject(value)) {
|
|
343
|
+
return Reflect.ownKeys(value);
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
return [];
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
else if (type === 'deleted') {
|
|
350
|
+
return [];
|
|
351
|
+
}
|
|
352
|
+
else if (type === 'map') {
|
|
353
|
+
const props = (_g = (_f = (_d = state.imo.$branches) === null || _d === void 0 ? void 0 : _d[(_e = state.imo.$type[1]) !== null && _e !== void 0 ? _e : 'base']) === null || _f === void 0 ? void 0 : _f.$mapProps) !== null && _g !== void 0 ? _g : {};
|
|
354
|
+
return Reflect.ownKeys(props).filter((key) => props[key].$type[0] !== 'deleted');
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
throw Error(`Unrecognized type: ${type}`);
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
deleteProperty(state, prop) {
|
|
361
|
+
var _a, _b, _c;
|
|
362
|
+
if (prop === DRAFT_STATE)
|
|
363
|
+
throw Error(`Unallowed`);
|
|
364
|
+
if (typeof prop !== 'string')
|
|
365
|
+
throw Error(`Non-string props are not allowed`);
|
|
366
|
+
const imo = state.imo;
|
|
367
|
+
const type = imo.$type[0];
|
|
368
|
+
const branchName = (_a = imo.$type[1]) !== null && _a !== void 0 ? _a : 'base';
|
|
369
|
+
if (type === 'deleted')
|
|
370
|
+
throw new Error(`This value is marked as deleted and cannot be changed`);
|
|
371
|
+
if (type === 'boxed')
|
|
372
|
+
throw new Error(`Implement deleting inside a boxed value`);
|
|
373
|
+
if (type === 'map') {
|
|
374
|
+
const mapProps = (_c = (_b = imo.$branches) === null || _b === void 0 ? void 0 : _b[branchName]) === null || _c === void 0 ? void 0 : _c.$mapProps;
|
|
375
|
+
if (!mapProps)
|
|
376
|
+
return false;
|
|
377
|
+
if (!Object.hasOwn(mapProps, prop))
|
|
378
|
+
return false;
|
|
379
|
+
if (!isCell(mapProps[prop]))
|
|
380
|
+
return false;
|
|
381
|
+
const currentPropCell = mapProps[prop];
|
|
382
|
+
if (currentPropCell.$type[0] === 'deleted')
|
|
383
|
+
return false;
|
|
384
|
+
currentPropCell.$type = ['deleted', generateBranchName()];
|
|
385
|
+
return true;
|
|
386
|
+
}
|
|
387
|
+
throw new Error(`Unrecognized type: ${type}`);
|
|
388
|
+
},
|
|
389
|
+
getOwnPropertyDescriptor(state, prop) {
|
|
390
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
391
|
+
const type = state.imo.$type[0];
|
|
392
|
+
if (type === 'boxed') {
|
|
393
|
+
const $boxedValue = (_c = (_a = state.imo.$branches) === null || _a === void 0 ? void 0 : _a[(_b = state.imo.$type[1]) !== null && _b !== void 0 ? _b : 'base']) === null || _c === void 0 ? void 0 : _c.$boxedValue;
|
|
394
|
+
if (isPlainObject($boxedValue)) {
|
|
395
|
+
return Reflect.getOwnPropertyDescriptor($boxedValue, prop);
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
return undefined;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
else if (type === 'deleted') {
|
|
402
|
+
return undefined;
|
|
403
|
+
}
|
|
404
|
+
else if (type === 'map') {
|
|
405
|
+
const props = (_g = (_f = (_d = state.imo.$branches) === null || _d === void 0 ? void 0 : _d[(_e = state.imo.$type[1]) !== null && _e !== void 0 ? _e : 'base']) === null || _f === void 0 ? void 0 : _f.$mapProps) !== null && _g !== void 0 ? _g : {};
|
|
406
|
+
if (Object.hasOwn(props, prop)) {
|
|
407
|
+
return {
|
|
408
|
+
writable: true,
|
|
409
|
+
configurable: true,
|
|
410
|
+
enumerable: true,
|
|
411
|
+
value: traps.get(state, prop, {}),
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
return undefined;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
throw Error(`Unrecognized type: ${type}`);
|
|
420
|
+
}
|
|
421
|
+
},
|
|
422
|
+
defineProperty(state, prop, descriptor) {
|
|
423
|
+
throw Error(`Implement defineProperty()`);
|
|
424
|
+
},
|
|
425
|
+
getPrototypeOf(state) {
|
|
426
|
+
var _a, _b, _c;
|
|
427
|
+
const type = state.imo.$type[0];
|
|
428
|
+
if (type === 'boxed') {
|
|
429
|
+
return Object.getPrototypeOf((_c = (_a = state.imo.$branches) === null || _a === void 0 ? void 0 : _a[(_b = state.imo.$type[1]) !== null && _b !== void 0 ? _b : 'base']) === null || _c === void 0 ? void 0 : _c.$boxedValue);
|
|
430
|
+
}
|
|
431
|
+
else if (type === 'deleted') {
|
|
432
|
+
return undefined;
|
|
433
|
+
}
|
|
434
|
+
else if (type === 'map') {
|
|
435
|
+
return Object.getPrototypeOf({});
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
throw Error(`Unrecognized type: ${type}`);
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
setPrototypeOf(state, prototype) {
|
|
442
|
+
throw Error(`Implement setPrototypeOf()`);
|
|
443
|
+
},
|
|
444
|
+
};
|
|
445
|
+
export const current = (draft) => {
|
|
446
|
+
if (typeof draft !== 'object' || draft === null) {
|
|
447
|
+
return draft;
|
|
448
|
+
}
|
|
449
|
+
const state = draft[DRAFT_STATE];
|
|
450
|
+
if (!state)
|
|
451
|
+
return draft;
|
|
452
|
+
const currentImo = immer.current(state.imo);
|
|
453
|
+
return jsonFromCell(currentImo);
|
|
454
|
+
};
|
|
455
|
+
function valueType(v) {
|
|
456
|
+
if (typeof v === 'object' && v) {
|
|
457
|
+
if (Array.isArray(v)) {
|
|
458
|
+
return { type: 'boxed', value: v };
|
|
459
|
+
}
|
|
460
|
+
return { type: 'map', value: v };
|
|
461
|
+
}
|
|
462
|
+
if (typeof v === 'string' ||
|
|
463
|
+
typeof v === 'number' ||
|
|
464
|
+
typeof v === 'boolean' ||
|
|
465
|
+
typeof v === 'undefined' ||
|
|
466
|
+
v === null) {
|
|
467
|
+
return { type: 'boxed', value: v };
|
|
468
|
+
}
|
|
469
|
+
throw Error(`Unrecognized value type: ${typeof v}`);
|
|
470
|
+
}
|
|
471
|
+
const DRAFT_STATE = Symbol.for('draft-state');
|
|
472
|
+
const objectCtorString = Object.prototype.constructor.toString();
|
|
473
|
+
export function isPlainObject(value) {
|
|
474
|
+
if (!value || typeof value !== 'object')
|
|
475
|
+
return false;
|
|
476
|
+
const proto = Object.getPrototypeOf(value);
|
|
477
|
+
if (proto === null) {
|
|
478
|
+
return true;
|
|
479
|
+
}
|
|
480
|
+
const Ctor = Object.hasOwnProperty.call(proto, 'constructor') && proto.constructor;
|
|
481
|
+
if (Ctor === Object)
|
|
482
|
+
return true;
|
|
483
|
+
return (typeof Ctor == 'function' &&
|
|
484
|
+
Function.toString.call(Ctor) === objectCtorString);
|
|
485
|
+
}
|
|
486
|
+
const BOXED = Symbol.for('boxed');
|
|
487
|
+
export function boxed(value) {
|
|
488
|
+
return { [BOXED]: true, value };
|
|
489
|
+
}
|
|
490
|
+
function isBoxed(value) {
|
|
491
|
+
return typeof value === 'object' &&
|
|
492
|
+
value &&
|
|
493
|
+
value[BOXED] === true
|
|
494
|
+
? true
|
|
495
|
+
: false;
|
|
496
|
+
}
|
|
497
|
+
const RESET = Symbol.for('reset');
|
|
498
|
+
export function reset(value) {
|
|
499
|
+
return { [RESET]: true, value };
|
|
500
|
+
}
|
|
501
|
+
function isReset(value) {
|
|
502
|
+
return typeof value === 'object' &&
|
|
503
|
+
value &&
|
|
504
|
+
value[RESET] === true
|
|
505
|
+
? true
|
|
506
|
+
: false;
|
|
507
|
+
}
|
|
508
|
+
function is(x, y) {
|
|
509
|
+
// Copied from https://github.com/immerjs/immer/blob/f6736a4beef727c6e5b41c312ce1b202ad3afb23/src/utils/common.ts#L115
|
|
510
|
+
// Originally from: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js
|
|
511
|
+
if (x === y) {
|
|
512
|
+
return x !== 0 || 1 / x === 1 / y;
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
return x !== x && y !== y;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
export function jsonFromCell(v) {
|
|
519
|
+
if (typeof v !== 'object' || v === null) {
|
|
520
|
+
return NOT_DEFINED;
|
|
521
|
+
}
|
|
522
|
+
return _jsonFromCell(v);
|
|
523
|
+
}
|
|
524
|
+
const _jsonFromCell = memoizeFn((v) => {
|
|
525
|
+
var _a, _b, _c, _d;
|
|
526
|
+
const type = (_a = v.$type) === null || _a === void 0 ? void 0 : _a[0];
|
|
527
|
+
const branchName = (_b = v.$branches) === null || _b === void 0 ? void 0 : _b[(_d = (_c = v.$type) === null || _c === void 0 ? void 0 : _c[1]) !== null && _d !== void 0 ? _d : 'base'];
|
|
528
|
+
if (typeof type !== 'string') {
|
|
529
|
+
return NOT_DEFINED;
|
|
530
|
+
}
|
|
531
|
+
if (type === 'deleted') {
|
|
532
|
+
return NOT_DEFINED;
|
|
533
|
+
}
|
|
534
|
+
if (type === 'boxed') {
|
|
535
|
+
return branchName === null || branchName === void 0 ? void 0 : branchName.$boxedValue;
|
|
536
|
+
}
|
|
537
|
+
if (v.$type[0] === 'map') {
|
|
538
|
+
const props = {};
|
|
539
|
+
for (const [k, _value] of Object.entries((branchName === null || branchName === void 0 ? void 0 : branchName.$mapProps) || {})) {
|
|
540
|
+
const value = jsonFromCell(_value);
|
|
541
|
+
if (value !== NOT_DEFINED) {
|
|
542
|
+
props[k] = value;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
return props;
|
|
546
|
+
}
|
|
547
|
+
return NOT_DEFINED;
|
|
548
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rogue.test.d.ts","sourceRoot":"","sources":["../src/rogue.test.ts"],"names":[],"mappings":""}
|