akanjs 3.0.0-alpha.36 → 3.0.0-alpha.37
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/local/apps/serverLifecycle/serverLifecycle-local.db-shm +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local_solid.db-shm +0 -0
- package/package.json +1 -1
- package/store/action.ts +5 -0
- package/store/formSetterNames.ts +9 -0
- package/store/storeRegistry.ts +23 -0
- package/types/store/formSetterNames.d.ts +9 -0
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
package/store/action.ts
CHANGED
|
@@ -316,6 +316,11 @@ export const makeFormSetter = (refName: string, fetch: FetchProxy<any>) => {
|
|
|
316
316
|
: (value as object);
|
|
317
317
|
(state[names.modelForm] as { [key: string]: any })[namesOfField.field] = setValue;
|
|
318
318
|
});
|
|
319
|
+
|
|
320
|
+
const postSet = (this as unknown as { [key: string]: ((value: unknown) => unknown) | undefined })[
|
|
321
|
+
namesOfField.postSetField
|
|
322
|
+
];
|
|
323
|
+
if (postSet) void postSet.call(this, value);
|
|
319
324
|
},
|
|
320
325
|
...(field.isArray
|
|
321
326
|
? {
|
package/store/formSetterNames.ts
CHANGED
|
@@ -17,5 +17,14 @@ export const formSetterNames = (className: string, key: string) => {
|
|
|
17
17
|
subFieldOnModel: `sub${classKeyName}On${className}`,
|
|
18
18
|
addOrSubFieldOnModel: `addOrSub${classKeyName}On${className}`,
|
|
19
19
|
uploadFieldOnModel: `upload${classKeyName}On${className}`,
|
|
20
|
+
/**
|
|
21
|
+
* The optional hook a store declares to run after this field is written.
|
|
22
|
+
*
|
|
23
|
+
* It carries no model suffix and a leading `_`, so it can never collide with a generated action name — which is
|
|
24
|
+
* the whole point: every generated action lives in a mapped type, and a mapped type produces *properties*, so a
|
|
25
|
+
* subclass method of the same name is a TS2425 error and there is no legal way to override one. A hook under a
|
|
26
|
+
* name the base type does not declare is the only shape TypeScript permits.
|
|
27
|
+
*/
|
|
28
|
+
postSetField: `_postSet${classKeyName}`,
|
|
20
29
|
};
|
|
21
30
|
};
|
package/store/storeRegistry.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ACTION_META,
|
|
3
3
|
ACTION_OWNER_META,
|
|
4
|
+
FIELD_META,
|
|
4
5
|
type MergeAllKeyOfObjects,
|
|
5
6
|
type MergeAllKeyOfTypes,
|
|
6
7
|
type MergeAllTypes,
|
|
@@ -9,7 +10,9 @@ import {
|
|
|
9
10
|
STATE_META,
|
|
10
11
|
} from "akanjs/base";
|
|
11
12
|
import { applyMixins } from "akanjs/common";
|
|
13
|
+
import { ConstantRegistry } from "akanjs/constant";
|
|
12
14
|
import { attachAgentic } from "./agentic";
|
|
15
|
+
import { formSetterNames } from "./formSetterNames";
|
|
13
16
|
import type { RootStoreCls } from "./rootStore";
|
|
14
17
|
import type { StoreCls } from "./store";
|
|
15
18
|
import { StoreInstance } from "./storeInstance";
|
|
@@ -57,8 +60,28 @@ export class StoreRegistry {
|
|
|
57
60
|
store[ACTION_META] = actions;
|
|
58
61
|
store[ACTION_OWNER_META] = owners;
|
|
59
62
|
StoreRegistry.#state.store.set(store.refName, store);
|
|
63
|
+
StoreRegistry.#warnUnknownPostSetHooks(store);
|
|
60
64
|
return store;
|
|
61
65
|
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* A `_postSet<Field>` hook cannot be typed — the generated setters live in a mapped type, so every name the base
|
|
69
|
+
* declares is a property a subclass method may not redeclare (TS2425), and the hook only compiles because the base
|
|
70
|
+
* declares nothing under it. A misspelled field would therefore never fire and never complain, so say so here.
|
|
71
|
+
*/
|
|
72
|
+
static #warnUnknownPostSetHooks(store: StoreCls) {
|
|
73
|
+
const hooks = Object.keys(Object.getOwnPropertyDescriptors(store.prototype)).filter((key) =>
|
|
74
|
+
key.startsWith("_postSet"),
|
|
75
|
+
);
|
|
76
|
+
if (!hooks.length) return;
|
|
77
|
+
const model = ConstantRegistry.getDatabase(store.refName, { allowEmpty: true });
|
|
78
|
+
if (!model) return;
|
|
79
|
+
const known = new Set(
|
|
80
|
+
Object.keys(model.full[FIELD_META] as object).map((key) => formSetterNames("", key).postSetField),
|
|
81
|
+
);
|
|
82
|
+
for (const hook of hooks.filter((key) => !known.has(key)))
|
|
83
|
+
console.warn(`[${store.refName}Store] ${hook} matches no field of ${store.refName}, so it will never run.`);
|
|
84
|
+
}
|
|
62
85
|
static get(refName: string) {
|
|
63
86
|
return StoreRegistry.#state.store.get(refName);
|
|
64
87
|
}
|
|
@@ -13,4 +13,13 @@ export declare const formSetterNames: (className: string, key: string) => {
|
|
|
13
13
|
subFieldOnModel: string;
|
|
14
14
|
addOrSubFieldOnModel: string;
|
|
15
15
|
uploadFieldOnModel: string;
|
|
16
|
+
/**
|
|
17
|
+
* The optional hook a store declares to run after this field is written.
|
|
18
|
+
*
|
|
19
|
+
* It carries no model suffix and a leading `_`, so it can never collide with a generated action name — which is
|
|
20
|
+
* the whole point: every generated action lives in a mapped type, and a mapped type produces *properties*, so a
|
|
21
|
+
* subclass method of the same name is a TS2425 error and there is no legal way to override one. A hook under a
|
|
22
|
+
* name the base type does not declare is the only shape TypeScript permits.
|
|
23
|
+
*/
|
|
24
|
+
postSetField: string;
|
|
16
25
|
};
|