@crustjs/store 0.4.1 → 0.4.2
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/dist/index.js +26 -10
- package/package.json +68 -70
package/dist/index.js
CHANGED
|
@@ -255,10 +255,22 @@ function resolveStorePath(dirPath, name) {
|
|
|
255
255
|
//#endregion
|
|
256
256
|
//#region src/merge.ts
|
|
257
257
|
/**
|
|
258
|
+
* Sets an own enumerable data property. Plain assignment would invoke the
|
|
259
|
+
* inherited `__proto__` setter instead of storing a `__proto__` field.
|
|
260
|
+
*/
|
|
261
|
+
function setDocumentValue(document, key, value) {
|
|
262
|
+
Object.defineProperty(document, key, {
|
|
263
|
+
value,
|
|
264
|
+
writable: true,
|
|
265
|
+
enumerable: true,
|
|
266
|
+
configurable: true
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
258
270
|
* Applies field defaults to a persisted config object.
|
|
259
271
|
*
|
|
260
272
|
* For each field defined in `fields`:
|
|
261
|
-
* - If the key
|
|
273
|
+
* - If `persisted` has the key as an own property, the persisted value is used.
|
|
262
274
|
* - If the key is missing and the field has a `default`, the default is used.
|
|
263
275
|
* Defaults are deep-copied to prevent shared nested mutation.
|
|
264
276
|
* - If the key is missing and no default exists, the field is omitted
|
|
@@ -274,10 +286,10 @@ function resolveStorePath(dirPath, name) {
|
|
|
274
286
|
*/
|
|
275
287
|
function applyFieldDefaults(persisted, fields, pruneUnknown = true) {
|
|
276
288
|
const result = {};
|
|
277
|
-
for (const [key, def] of Object.entries(fields)) if (persisted && key
|
|
278
|
-
else if ("default" in def && def.default !== void 0) result
|
|
289
|
+
for (const [key, def] of Object.entries(fields)) if (persisted && Object.hasOwn(persisted, key)) setDocumentValue(result, key, persisted[key]);
|
|
290
|
+
else if ("default" in def && def.default !== void 0) setDocumentValue(result, key, structuredClone(def.default));
|
|
279
291
|
if (!pruneUnknown && persisted !== void 0) {
|
|
280
|
-
for (const [key, value] of Object.entries(persisted)) if (!(key
|
|
292
|
+
for (const [key, value] of Object.entries(persisted)) if (!Object.hasOwn(fields, key)) setDocumentValue(result, key, value);
|
|
281
293
|
}
|
|
282
294
|
return result;
|
|
283
295
|
}
|
|
@@ -488,21 +500,25 @@ function createStore(options) {
|
|
|
488
500
|
function normalizeStateTypes(state) {
|
|
489
501
|
const normalized = { ...state };
|
|
490
502
|
for (const [key, def] of Object.entries(fields)) {
|
|
491
|
-
if (!(
|
|
503
|
+
if (!Object.hasOwn(normalized, key)) {
|
|
504
|
+
if (key in normalized) setDocumentValue(normalized, key, void 0);
|
|
505
|
+
continue;
|
|
506
|
+
}
|
|
507
|
+
if (def.schema !== void 0) continue;
|
|
492
508
|
const value = normalized[key];
|
|
493
509
|
if (value === void 0) continue;
|
|
494
510
|
if (def.array === true && Array.isArray(value)) {
|
|
495
|
-
normalized
|
|
511
|
+
setDocumentValue(normalized, key, value.map((item) => coerceByType(item, def.type)));
|
|
496
512
|
continue;
|
|
497
513
|
}
|
|
498
|
-
normalized
|
|
514
|
+
setDocumentValue(normalized, key, coerceByType(value, def.type));
|
|
499
515
|
}
|
|
500
516
|
return normalized;
|
|
501
517
|
}
|
|
502
518
|
async function runFieldValidators(mutableState, operation) {
|
|
503
519
|
const issues = [];
|
|
504
520
|
for (const [key, def] of Object.entries(fields)) {
|
|
505
|
-
const value = mutableState[key];
|
|
521
|
+
const value = Object.hasOwn(mutableState, key) ? mutableState[key] : void 0;
|
|
506
522
|
if (value === void 0 && def.schema === void 0) {
|
|
507
523
|
if (def.default !== void 0) issues.push({
|
|
508
524
|
message: expectedTypeMessage(def),
|
|
@@ -534,7 +550,7 @@ function createStore(options) {
|
|
|
534
550
|
if (isFieldValueResult(result)) {
|
|
535
551
|
const transformed = result.value;
|
|
536
552
|
if (operation === "read") {
|
|
537
|
-
if (def.schema !== void 0) mutableState
|
|
553
|
+
if (def.schema !== void 0) setDocumentValue(mutableState, key, transformed);
|
|
538
554
|
continue;
|
|
539
555
|
}
|
|
540
556
|
if (def.schema === void 0 && !matchesDeclaredType(def, transformed)) {
|
|
@@ -563,7 +579,7 @@ function createStore(options) {
|
|
|
563
579
|
});
|
|
564
580
|
continue;
|
|
565
581
|
}
|
|
566
|
-
mutableState
|
|
582
|
+
setDocumentValue(mutableState, key, transformed);
|
|
567
583
|
}
|
|
568
584
|
}
|
|
569
585
|
}
|
package/package.json
CHANGED
|
@@ -1,71 +1,69 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
}
|
|
2
|
+
"name": "@crustjs/store",
|
|
3
|
+
"version": "0.4.2",
|
|
4
|
+
"description": "DX-first, typed persistence for CLI apps with config/data/state/cache separation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"author": "chenxin-yan",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/chenxin-yan/crust.git",
|
|
12
|
+
"directory": "packages/store"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://crustjs.com",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/chenxin-yan/crust/issues"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"cli",
|
|
20
|
+
"config",
|
|
21
|
+
"data",
|
|
22
|
+
"state",
|
|
23
|
+
"cache",
|
|
24
|
+
"store",
|
|
25
|
+
"persistence",
|
|
26
|
+
"xdg",
|
|
27
|
+
"bun",
|
|
28
|
+
"typescript"
|
|
29
|
+
],
|
|
30
|
+
"files": [
|
|
31
|
+
"dist"
|
|
32
|
+
],
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"import": "./dist/index.js"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@crustjs/utils": "^0.2.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@crustjs/config": "0.0.0",
|
|
47
|
+
"zod": "^4.5.4",
|
|
48
|
+
"vite-plus": "1.0.0-rc.0"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"typescript": "^7.0.0"
|
|
52
|
+
},
|
|
53
|
+
"peerDependenciesMeta": {
|
|
54
|
+
"typescript": {
|
|
55
|
+
"optional": true
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"bun": ">=1.4.0",
|
|
60
|
+
"node": ">=22",
|
|
61
|
+
"deno": ">=2.8"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"build": "vp run build:task",
|
|
65
|
+
"dev": "vp pack --watch",
|
|
66
|
+
"check:types": "vp run check:types:task",
|
|
67
|
+
"test": "vp run test:task"
|
|
68
|
+
}
|
|
69
|
+
}
|