akanjs 2.3.9-rc.1 → 2.3.9-rc.10
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/README.ko.md +1 -1
- package/README.md +1 -1
- package/constant/fieldInfo.ts +2 -1
- package/fetch/client/fetchClient.ts +2 -2
- package/fetch/fetchType/endpointFetch.type.ts +2 -2
- package/fetch/fetchType/sliceFetch.type.ts +16 -14
- package/local/apps/serverLifecycle/serverLifecycle-local.db +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local.db-shm +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local.db-wal +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local_solid.db +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local_solid.db-shm +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local_solid.db-wal +0 -0
- package/package.json +1 -1
- package/server/di/diLifecycle.ts +58 -30
- package/server/di/utils.ts +64 -0
- package/signal/endpointInfo.ts +16 -4
- package/signal/internalInfo.ts +9 -4
- package/types/constant/fieldInfo.d.ts +2 -1
- package/types/fetch/fetchType/endpointFetch.type.d.ts +2 -2
- package/types/fetch/fetchType/sliceFetch.type.d.ts +5 -5
- package/types/server/di/utils.d.ts +13 -0
package/README.ko.md
CHANGED
|
@@ -220,7 +220,7 @@ akan update
|
|
|
220
220
|
|
|
221
221
|
주요 영역:
|
|
222
222
|
|
|
223
|
-
- **Workspace**: workspace 생성,
|
|
223
|
+
- **Workspace**: workspace 생성, lint, sync.
|
|
224
224
|
- **Application**: app start, build, typecheck, package, release.
|
|
225
225
|
- **Library**: shared library 생성, 설치, sync, push, pull.
|
|
226
226
|
- **Module and scalar**: domain module, model, view, unit, template, store 생성.
|
package/README.md
CHANGED
|
@@ -218,7 +218,7 @@ akan update
|
|
|
218
218
|
|
|
219
219
|
Common areas:
|
|
220
220
|
|
|
221
|
-
- **Workspace**: create workspaces,
|
|
221
|
+
- **Workspace**: create workspaces, lint and sync projects.
|
|
222
222
|
- **Application**: start, build, typecheck, package, and release apps.
|
|
223
223
|
- **Library**: create, install, sync, push, and pull shared libraries.
|
|
224
224
|
- **Module and scalar**: generate domain modules, models, views, units, templates, and stores.
|
package/constant/fieldInfo.ts
CHANGED
|
@@ -26,7 +26,8 @@ export type ParamFieldType =
|
|
|
26
26
|
})
|
|
27
27
|
| EnumInstance<string, any>;
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
type ConstantFieldEnumType = EnumInstance<string, any>;
|
|
30
|
+
export type ConstantFieldType = typeof PrimitiveScalar | ConstantModelRef | MapConstructor | ConstantFieldEnumType;
|
|
30
31
|
export type ConstantFieldTypeInput =
|
|
31
32
|
| ConstantFieldType
|
|
32
33
|
| ConstantFieldType[]
|
|
@@ -274,7 +274,7 @@ export class FetchClient {
|
|
|
274
274
|
const serializerMap = this.#makeArgSerializer(endpoint.args);
|
|
275
275
|
const parseReturn = this.#makeReturnParser(endpoint.returns);
|
|
276
276
|
const wrappedListeners = new WeakMap<(data: unknown) => void, (data: unknown) => void>();
|
|
277
|
-
return
|
|
277
|
+
return (...argData: unknown[]) => {
|
|
278
278
|
const args = argData.slice(0, roomArgLength);
|
|
279
279
|
const handleEvent = argData[roomArgLength] as (data: unknown) => void;
|
|
280
280
|
const fetchPolicy = argData[roomArgLength + 1] as FetchPolicy | undefined;
|
|
@@ -300,7 +300,7 @@ export class FetchClient {
|
|
|
300
300
|
const msgArgs = endpoint.args.filter((arg) => arg.type === "msg");
|
|
301
301
|
const msgArgLength = msgArgs.length;
|
|
302
302
|
const serializerMap = this.#makeArgSerializer(endpoint.args);
|
|
303
|
-
return
|
|
303
|
+
return (...argData: unknown[]) => {
|
|
304
304
|
const args = argData.slice(0, msgArgLength);
|
|
305
305
|
const data = msgArgs.map((arg, idx) => serializerMap.get(arg.name)?.(args[idx]) ?? null);
|
|
306
306
|
this.ws.emit(key, data);
|
|
@@ -40,7 +40,7 @@ type QueryOrMutationFetchFn<E, SlceCls extends SliceCls | never> = (
|
|
|
40
40
|
...args: [...EndpInfoArgs<E>, fetchPolicy?: FetchPolicy]
|
|
41
41
|
) => Promise<EndpInfoReturns<E, SlceCls>>;
|
|
42
42
|
|
|
43
|
-
type MessageEmitFn<E
|
|
43
|
+
type MessageEmitFn<E> = (...args: EndpInfoArgs<E>) => void;
|
|
44
44
|
|
|
45
45
|
type MessageListenFn<E, SlceCls extends SliceCls | never> = (
|
|
46
46
|
handleEvent: (data: EndpInfoReturns<E, SlceCls>) => PromiseOrObject<void>,
|
|
@@ -59,7 +59,7 @@ type PrimaryFetchFn<E, SlceCls extends SliceCls | never> =
|
|
|
59
59
|
EndpInfoReqType<E> extends "query" | "mutation"
|
|
60
60
|
? QueryOrMutationFetchFn<E, SlceCls>
|
|
61
61
|
: EndpInfoReqType<E> extends "message"
|
|
62
|
-
? MessageEmitFn<E
|
|
62
|
+
? MessageEmitFn<E>
|
|
63
63
|
: never;
|
|
64
64
|
|
|
65
65
|
type PrimaryFetchType<EInfoObj extends { [key: string]: EndpointInfo }, SlceCls extends SliceCls | never> = {
|
|
@@ -16,7 +16,7 @@ import type {
|
|
|
16
16
|
SliceCls,
|
|
17
17
|
SliceInfoArgs,
|
|
18
18
|
} from "akanjs/signal";
|
|
19
|
-
import type {
|
|
19
|
+
import type { EditReturn, InitReturn, ServerEdit, ServerInit, ServerView, ViewReturn } from "./appliedReturn.type";
|
|
20
20
|
|
|
21
21
|
type _SliceMap<S extends SliceCls> = S[typeof SLICE_META];
|
|
22
22
|
type _RefName<S extends SliceCls> = SlceCnstRefName<S>;
|
|
@@ -74,16 +74,18 @@ type SliceInitFetch<S extends SliceCls> = {
|
|
|
74
74
|
type SliceGetInitFetch<S extends SliceCls> = {
|
|
75
75
|
[Suffix in keyof _SliceMap<S> as Suffix extends string ? `get${_Cap<S>}Init${Capitalize<Suffix>}` : never]: (
|
|
76
76
|
...args: [...SliceInfoArgs<_SliceMap<S>[Suffix]>, option?: _SliceFetchInitOption<S>]
|
|
77
|
-
) =>
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
77
|
+
) => Promise<
|
|
78
|
+
ServerInit<
|
|
79
|
+
_RefName<S>,
|
|
80
|
+
_Light<S>,
|
|
81
|
+
_Insight<S>,
|
|
82
|
+
SliceInfoArgs<_SliceMap<S>[Suffix]>,
|
|
83
|
+
_Filter<S>,
|
|
84
|
+
_Cap<S>,
|
|
85
|
+
GetStateObject<_LightWithId<S>>,
|
|
86
|
+
GetStateObject<_Insight<S>>,
|
|
87
|
+
_Sort<S>
|
|
88
|
+
>
|
|
87
89
|
>;
|
|
88
90
|
};
|
|
89
91
|
|
|
@@ -131,7 +133,7 @@ type RawBaseSliceFetchType<
|
|
|
131
133
|
fetchPolicy?: FetchPolicy,
|
|
132
134
|
) => Promise<Full>;
|
|
133
135
|
} & {
|
|
134
|
-
[K in `remove${_CapitalizedRefName}`]: (id: string, fetchPolicy?: FetchPolicy) => Promise<
|
|
136
|
+
[K in `remove${_CapitalizedRefName}`]: (id: string, fetchPolicy?: FetchPolicy) => Promise<Full>;
|
|
135
137
|
};
|
|
136
138
|
|
|
137
139
|
type AppliedBaseSliceFetchType<
|
|
@@ -143,11 +145,11 @@ type AppliedBaseSliceFetchType<
|
|
|
143
145
|
> = {
|
|
144
146
|
[K in `view${_CapitalizedRefName}`]: (id: string, option?: FetchPolicy) => Promise<ViewReturn<RefName, Full>>;
|
|
145
147
|
} & {
|
|
146
|
-
[K in `get${_CapitalizedRefName}View`]: (id: string, option?: FetchPolicy) =>
|
|
148
|
+
[K in `get${_CapitalizedRefName}View`]: (id: string, option?: FetchPolicy) => Promise<ServerView<RefName, Full>>;
|
|
147
149
|
} & {
|
|
148
150
|
[K in `edit${_CapitalizedRefName}`]: (id: string, option?: FetchPolicy) => Promise<EditReturn<RefName, Full>>;
|
|
149
151
|
} & {
|
|
150
|
-
[K in `get${_CapitalizedRefName}Edit`]: (id: string, option?: FetchPolicy) =>
|
|
152
|
+
[K in `get${_CapitalizedRefName}Edit`]: (id: string, option?: FetchPolicy) => Promise<ServerEdit<RefName, Full>>;
|
|
151
153
|
} & {
|
|
152
154
|
[K in `add${_CapitalizedRefName}Files`]: (
|
|
153
155
|
fileList: FileList,
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
package/server/di/diLifecycle.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BaseEnv } from "akanjs/base";
|
|
2
|
-
import { Logger
|
|
2
|
+
import { Logger } from "akanjs/common";
|
|
3
3
|
import {
|
|
4
4
|
type Adaptor,
|
|
5
5
|
type AdaptorCls,
|
|
@@ -26,29 +26,17 @@ import type { SignalRoutes, WebsocketRoutes } from "../types";
|
|
|
26
26
|
import { getPredefinedAdaptor, predefinedAdaptorRole } from "./predefinedAdaptor";
|
|
27
27
|
import { collectAdaptors, resolveAdaptorHierarchy } from "./resolveAdaptorHierarchy";
|
|
28
28
|
import { resolveServiceHierarchy } from "./resolveServiceHierarchy";
|
|
29
|
-
import {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const normalizeServiceRefName = (refName: string) => {
|
|
42
|
-
const normalized = lowerlize(refName);
|
|
43
|
-
return normalized.endsWith("Service") ? normalized.slice(0, -"Service".length) : normalized;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const normalizeSignalRefName = (refName: string) => {
|
|
47
|
-
const normalized = lowerlize(refName);
|
|
48
|
-
return normalized.endsWith("Signal") ? normalized : `${normalized}Signal`;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const normalizeAdaptorRefName = (refName: string) => lowerlize(refName);
|
|
29
|
+
import {
|
|
30
|
+
type DiModuleCandidate,
|
|
31
|
+
getModuleDependencyRefNames,
|
|
32
|
+
isDestroyableUse,
|
|
33
|
+
normalizeAdaptorRefName,
|
|
34
|
+
normalizeServiceRefName,
|
|
35
|
+
normalizeSignalRefName,
|
|
36
|
+
reasonMessage,
|
|
37
|
+
runStage,
|
|
38
|
+
toError,
|
|
39
|
+
} from "./utils";
|
|
52
40
|
|
|
53
41
|
/**
|
|
54
42
|
* Owns the app's DI container state (registry + live maps + init order) and
|
|
@@ -88,25 +76,32 @@ export class DiLifecycle {
|
|
|
88
76
|
this.#middleware.set(middleware.refName, middleware);
|
|
89
77
|
});
|
|
90
78
|
this.webProxies.push(...defaultOption.getWebProxies());
|
|
79
|
+
const databaseCandidates = new Map<string, DiModuleCandidate>();
|
|
80
|
+
const serviceCandidates = new Map<string, DiModuleCandidate>();
|
|
91
81
|
libs.forEach((lib) => {
|
|
92
82
|
lib.option.getMiddlewares().forEach((middleware) => {
|
|
93
83
|
this.#middleware.set(middleware.refName, middleware);
|
|
94
84
|
});
|
|
95
85
|
this.webProxies.push(...lib.option.getWebProxies());
|
|
96
86
|
lib.database.forEach((mod) => {
|
|
97
|
-
|
|
98
|
-
if (!mod.service.srv.enabled) return;
|
|
99
|
-
this.#database.set(mod.constant.refName, mod);
|
|
87
|
+
databaseCandidates.set(mod.constant.refName, { refName: mod.constant.refName, module: mod });
|
|
100
88
|
});
|
|
101
89
|
lib.service.forEach((mod) => {
|
|
102
|
-
|
|
103
|
-
if (!mod.service.srv.enabled) return;
|
|
104
|
-
this.#service.set(mod.service.srv.refName, mod);
|
|
90
|
+
serviceCandidates.set(mod.service.srv.refName, { refName: mod.service.srv.refName, module: mod });
|
|
105
91
|
});
|
|
106
92
|
lib.scalar.forEach((mod) => {
|
|
107
93
|
this.#scalar.set(mod.constant.refName, mod);
|
|
108
94
|
});
|
|
109
95
|
});
|
|
96
|
+
const disabledModules = this.#resolveDisabledModules(databaseCandidates, serviceCandidates);
|
|
97
|
+
databaseCandidates.forEach(({ refName, module }) => {
|
|
98
|
+
if (disabledModules.has(refName)) return;
|
|
99
|
+
this.#database.set(refName, module as DatabaseModule);
|
|
100
|
+
});
|
|
101
|
+
serviceCandidates.forEach(({ refName, module }) => {
|
|
102
|
+
if (disabledModules.has(refName)) return;
|
|
103
|
+
this.#service.set(refName, module as ServiceModule);
|
|
104
|
+
});
|
|
110
105
|
this.#database.forEach((mod) => {
|
|
111
106
|
const databaseAdaptor = DatabaseResolver.resolveDatabase(mod.constant, mod.database);
|
|
112
107
|
this.#adaptor.set(databaseAdaptor.refName, databaseAdaptor);
|
|
@@ -120,6 +115,39 @@ export class DiLifecycle {
|
|
|
120
115
|
}
|
|
121
116
|
}
|
|
122
117
|
|
|
118
|
+
#resolveDisabledModules(
|
|
119
|
+
databaseCandidates: Map<string, DiModuleCandidate>,
|
|
120
|
+
serviceCandidates: Map<string, DiModuleCandidate>,
|
|
121
|
+
) {
|
|
122
|
+
const candidates = new Map<string, DiModuleCandidate>([...databaseCandidates, ...serviceCandidates]);
|
|
123
|
+
const disabledReasons = new Map<string, string>();
|
|
124
|
+
|
|
125
|
+
candidates.forEach(({ refName, module }) => {
|
|
126
|
+
if (!module.service.srv.enabled) disabledReasons.set(refName, "service disabled");
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
let changed = true;
|
|
130
|
+
while (changed) {
|
|
131
|
+
changed = false;
|
|
132
|
+
candidates.forEach(({ refName, module }) => {
|
|
133
|
+
if (disabledReasons.has(refName)) return;
|
|
134
|
+
for (const dependencyRefName of getModuleDependencyRefNames(module)) {
|
|
135
|
+
if (dependencyRefName === refName) continue;
|
|
136
|
+
const dependencyReason = disabledReasons.get(dependencyRefName);
|
|
137
|
+
if (!dependencyReason) continue;
|
|
138
|
+
disabledReasons.set(refName, `depends on disabled module "${dependencyRefName}"`);
|
|
139
|
+
changed = true;
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
disabledReasons.forEach((reason, refName) => {
|
|
146
|
+
this.logger.verbose(`Skipping disabled module "${refName}": ${reason}`);
|
|
147
|
+
});
|
|
148
|
+
return new Set(disabledReasons.keys());
|
|
149
|
+
}
|
|
150
|
+
|
|
123
151
|
/** Run every init stage in dependency order and collect the generated routes. */
|
|
124
152
|
async initializeAll(): Promise<SignalRoutes> {
|
|
125
153
|
await this.#initializeUses();
|
package/server/di/utils.ts
CHANGED
|
@@ -1,8 +1,72 @@
|
|
|
1
|
+
import { INJECT_META } from "akanjs/base";
|
|
2
|
+
import { lowerlize } from "akanjs/common";
|
|
3
|
+
import type { InjectInfo } from "akanjs/service";
|
|
4
|
+
import type { DatabaseModule, ServiceModule } from "../akanLib";
|
|
5
|
+
|
|
1
6
|
interface StageTask {
|
|
2
7
|
label: string;
|
|
3
8
|
run: () => Promise<unknown>;
|
|
4
9
|
}
|
|
5
10
|
|
|
11
|
+
interface DestroyableUse {
|
|
12
|
+
onDestroy(): Promise<void> | void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type InjectableCls = { [INJECT_META]?: unknown };
|
|
16
|
+
|
|
17
|
+
export interface DiModuleCandidate {
|
|
18
|
+
refName: string;
|
|
19
|
+
module: DatabaseModule | ServiceModule;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const isDestroyableUse = (value: unknown): value is DestroyableUse =>
|
|
23
|
+
typeof value === "object" &&
|
|
24
|
+
value !== null &&
|
|
25
|
+
"onDestroy" in value &&
|
|
26
|
+
typeof (value as { onDestroy?: unknown }).onDestroy === "function";
|
|
27
|
+
|
|
28
|
+
export const normalizeServiceRefName = (refName: string) => {
|
|
29
|
+
const normalized = lowerlize(refName);
|
|
30
|
+
return normalized.endsWith("Service") ? normalized.slice(0, -"Service".length) : normalized;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const normalizeSignalRefName = (refName: string) => {
|
|
34
|
+
const normalized = lowerlize(refName);
|
|
35
|
+
return normalized.endsWith("Signal") ? normalized : `${normalized}Signal`;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const normalizeAdaptorRefName = (refName: string) => lowerlize(refName);
|
|
39
|
+
|
|
40
|
+
const normalizeInjectedServiceRefName = (propKey: string) =>
|
|
41
|
+
propKey.endsWith("Service") ? propKey.slice(0, -"Service".length) : propKey;
|
|
42
|
+
|
|
43
|
+
const normalizeInjectedDatabaseRefName = (propKey: string) =>
|
|
44
|
+
propKey.endsWith("Model") ? propKey.slice(0, -"Model".length) : propKey;
|
|
45
|
+
|
|
46
|
+
const normalizeInjectedSignalRefName = (propKey: string) => {
|
|
47
|
+
const normalized = lowerlize(propKey);
|
|
48
|
+
return normalized.endsWith("Signal") ? normalized.slice(0, -"Signal".length) : normalized;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const getModuleInjectables = (mod: DatabaseModule | ServiceModule): InjectableCls[] => {
|
|
52
|
+
const injectables: InjectableCls[] = [mod.service.srv, mod.signal.internal, mod.signal.endpoint, mod.signal.server];
|
|
53
|
+
if ("constant" in mod) injectables.push(mod.signal.slice);
|
|
54
|
+
return injectables;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const getModuleDependencyRefNames = (mod: DatabaseModule | ServiceModule) => {
|
|
58
|
+
const dependencies = new Set<string>();
|
|
59
|
+
for (const injectable of getModuleInjectables(mod)) {
|
|
60
|
+
const injectMap = (injectable[INJECT_META] ?? {}) as Record<string, InjectInfo>;
|
|
61
|
+
for (const [propKey, injectInfo] of Object.entries(injectMap)) {
|
|
62
|
+
if (injectInfo.type === "service") dependencies.add(normalizeInjectedServiceRefName(propKey));
|
|
63
|
+
else if (injectInfo.type === "database") dependencies.add(normalizeInjectedDatabaseRefName(propKey));
|
|
64
|
+
else if (injectInfo.type === "signal") dependencies.add(normalizeInjectedSignalRefName(propKey));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return dependencies;
|
|
68
|
+
};
|
|
69
|
+
|
|
6
70
|
/**
|
|
7
71
|
* Run every task in parallel and, if any rejects, throw a single
|
|
8
72
|
* `AggregateError` that enumerates every failing label + cause. This replaces
|
package/signal/endpointInfo.ts
CHANGED
|
@@ -344,10 +344,22 @@ export type BuildEndpoint<SrvModule extends ServiceModel = ServiceModel> = {
|
|
|
344
344
|
};
|
|
345
345
|
|
|
346
346
|
export const buildEndpoint = {
|
|
347
|
-
query:
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
347
|
+
query: <Returns extends ConstantFieldTypeInput, Nullable extends boolean = false>(
|
|
348
|
+
returnRef: Returns,
|
|
349
|
+
signalOption?: SignalOption<Returns, Nullable>,
|
|
350
|
+
) => new EndpointInfo("query", returnRef, signalOption),
|
|
351
|
+
mutation: <Returns extends ConstantFieldTypeInput, Nullable extends boolean = false>(
|
|
352
|
+
returnRef: Returns,
|
|
353
|
+
signalOption?: SignalOption<Returns, Nullable>,
|
|
354
|
+
) => new EndpointInfo("mutation", returnRef, signalOption),
|
|
355
|
+
pubsub: <Returns extends ConstantFieldTypeInput, Nullable extends boolean = false>(
|
|
356
|
+
returnRef: Returns,
|
|
357
|
+
signalOption?: SignalOption<Returns, Nullable>,
|
|
358
|
+
) => new EndpointInfo("pubsub", returnRef, signalOption),
|
|
359
|
+
message: <Returns extends ConstantFieldTypeInput, Nullable extends boolean = false>(
|
|
360
|
+
returnRef: Returns,
|
|
361
|
+
signalOption?: SignalOption<Returns, Nullable>,
|
|
362
|
+
) => new EndpointInfo("message", returnRef, signalOption),
|
|
351
363
|
} as unknown as BuildEndpoint<any>;
|
|
352
364
|
|
|
353
365
|
export type EndpointBuilder<SrvModule extends ServiceModel = ServiceModel> = (builder: BuildEndpoint<SrvModule>) => {
|
package/signal/internalInfo.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Any, type
|
|
1
|
+
import { Any, type FIELD_META, type PromiseOrObject } from "akanjs/base";
|
|
2
2
|
import type {
|
|
3
3
|
ConstantCls,
|
|
4
4
|
ConstantField,
|
|
@@ -209,8 +209,10 @@ export type InternalBuilder<
|
|
|
209
209
|
} & { [key: string]: InternalInfo<InternalType> };
|
|
210
210
|
|
|
211
211
|
export const buildInternal = {
|
|
212
|
-
resolveField:
|
|
213
|
-
|
|
212
|
+
resolveField: <Returns extends ConstantFieldTypeInput, Nullable extends boolean = false>(
|
|
213
|
+
returnRef: Returns,
|
|
214
|
+
signalOption?: Pick<SignalOption<Returns, Nullable>, "nullable">,
|
|
215
|
+
) => new InternalInfo("resolveField", returnRef, signalOption),
|
|
214
216
|
interval: (scheduleTime: number, signalOption?: SignalOption) =>
|
|
215
217
|
new InternalInfo("interval", Any, {
|
|
216
218
|
enabled: true,
|
|
@@ -248,7 +250,10 @@ export const buildInternal = {
|
|
|
248
250
|
scheduleType: "destroy",
|
|
249
251
|
...signalOption,
|
|
250
252
|
}),
|
|
251
|
-
process:
|
|
253
|
+
process: <Returns extends ConstantFieldTypeInput, Nullable extends boolean = false>(
|
|
254
|
+
returnRef: Returns,
|
|
255
|
+
signalOption?: SignalOption<Returns, Nullable>,
|
|
256
|
+
) =>
|
|
252
257
|
new InternalInfo("process", returnRef, {
|
|
253
258
|
serverMode: "all",
|
|
254
259
|
...signalOption,
|
|
@@ -4,7 +4,8 @@ import type { ConstantModelRef } from "./via.d.ts";
|
|
|
4
4
|
export type ParamFieldType = (typeof PrimitiveScalar & {
|
|
5
5
|
[CLIENT_VALUE]: string | number | boolean | Dayjs;
|
|
6
6
|
}) | EnumInstance<string, any>;
|
|
7
|
-
|
|
7
|
+
type ConstantFieldEnumType = EnumInstance<string, any>;
|
|
8
|
+
export type ConstantFieldType = typeof PrimitiveScalar | ConstantModelRef | MapConstructor | ConstantFieldEnumType;
|
|
8
9
|
export type ConstantFieldTypeInput = ConstantFieldType | ConstantFieldType[] | ConstantFieldType[][] | ConstantFieldType[][][];
|
|
9
10
|
export type FieldToValue<Field, MapValue = any> = Field extends null ? FieldToValue<Exclude<Field, null>> | null : Field extends MapConstructor ? Map<string, FieldToValue<MapValue>> : Field extends (infer F)[] ? FieldToValue<F>[] : Field extends typeof PrimitiveScalar | StringConstructor | BooleanConstructor | DateConstructor ? Field[typeof SERVER_VALUE] : Field extends ConstantModelRef ? UnCls<Field> : Field extends {
|
|
10
11
|
[SERVER_VALUE]: infer V;
|
|
@@ -5,14 +5,14 @@ type ExtendedEndpointReturn<ClientReturns, Full, Light, Insight> = ClientReturns
|
|
|
5
5
|
type EndpointClientReturns<E, SlceCls extends SliceCls | never> = [SlceCls] extends [never] ? EndpInfoClientReturns<E> : ExtendedEndpointReturn<EndpInfoClientReturns<E>, SlceCnstFull<SlceCls>, SlceCnstLight<SlceCls>, SlceCnstInsight<SlceCls>>;
|
|
6
6
|
type EndpInfoReturns<E, SlceCls extends SliceCls | never> = EndpointClientReturns<E, SlceCls> | (EndpInfoNullable<E> extends true ? null : never);
|
|
7
7
|
type QueryOrMutationFetchFn<E, SlceCls extends SliceCls | never> = (...args: [...EndpInfoArgs<E>, fetchPolicy?: FetchPolicy]) => Promise<EndpInfoReturns<E, SlceCls>>;
|
|
8
|
-
type MessageEmitFn<E
|
|
8
|
+
type MessageEmitFn<E> = (...args: EndpInfoArgs<E>) => void;
|
|
9
9
|
type MessageListenFn<E, SlceCls extends SliceCls | never> = (handleEvent: (data: EndpInfoReturns<E, SlceCls>) => PromiseOrObject<void>, options?: FetchPolicy) => () => void;
|
|
10
10
|
type PubsubSubscribeFn<E, SlceCls extends SliceCls | never> = (...args: [
|
|
11
11
|
...EndpInfoArgs<E>,
|
|
12
12
|
handleEvent: (data: EndpInfoReturns<E, SlceCls>) => PromiseOrObject<void>,
|
|
13
13
|
options?: FetchPolicy
|
|
14
14
|
]) => () => void;
|
|
15
|
-
type PrimaryFetchFn<E, SlceCls extends SliceCls | never> = EndpInfoReqType<E> extends "query" | "mutation" ? QueryOrMutationFetchFn<E, SlceCls> : EndpInfoReqType<E> extends "message" ? MessageEmitFn<E
|
|
15
|
+
type PrimaryFetchFn<E, SlceCls extends SliceCls | never> = EndpInfoReqType<E> extends "query" | "mutation" ? QueryOrMutationFetchFn<E, SlceCls> : EndpInfoReqType<E> extends "message" ? MessageEmitFn<E> : never;
|
|
16
16
|
type PrimaryFetchType<EInfoObj extends {
|
|
17
17
|
[key: string]: EndpointInfo;
|
|
18
18
|
}, SlceCls extends SliceCls | never> = {
|
|
@@ -3,7 +3,7 @@ import type { FetchPolicy } from "akanjs/common";
|
|
|
3
3
|
import type { ConstantModel, DefaultOf, ProtoFile, PurifiedModel } from "akanjs/constant";
|
|
4
4
|
import type { DatabaseModel, ExtractSort, FilterInstance } from "akanjs/document";
|
|
5
5
|
import type { SlceCnstCapitalizedRefName, SlceCnstDefaultInput, SlceCnstFull, SlceCnstInput, SlceCnstInsight, SlceCnstLight, SlceCnstPurifiedInput, SlceCnstRefName, SlceDbFilter, SlceDbSort, SliceCls, SliceInfoArgs } from "akanjs/signal";
|
|
6
|
-
import type {
|
|
6
|
+
import type { EditReturn, InitReturn, ServerEdit, ServerInit, ServerView, ViewReturn } from "./appliedReturn.type";
|
|
7
7
|
type _SliceMap<S extends SliceCls> = S[typeof SLICE_META];
|
|
8
8
|
type _RefName<S extends SliceCls> = SlceCnstRefName<S>;
|
|
9
9
|
type _Cap<S extends SliceCls> = SlceCnstCapitalizedRefName<S>;
|
|
@@ -37,7 +37,7 @@ type SliceInitFetch<S extends SliceCls> = {
|
|
|
37
37
|
[Suffix in keyof _SliceMap<S> as Suffix extends string ? `init${_Cap<S>}${Capitalize<Suffix>}` : never]: (...args: [...SliceInfoArgs<_SliceMap<S>[Suffix]>, option?: _SliceFetchInitOption<S>]) => Promise<InitReturn<_RefName<S>, Suffix & string, _Light<S>, _Insight<S>, SliceInfoArgs<_SliceMap<S>[Suffix]>, _Filter<S>, _Cap<S>, Suffix extends string ? Capitalize<Suffix> : never, _LightWithId<S>, GetStateObject<_LightWithId<S>>, GetStateObject<_Insight<S>>, _Sort<S>>>;
|
|
38
38
|
};
|
|
39
39
|
type SliceGetInitFetch<S extends SliceCls> = {
|
|
40
|
-
[Suffix in keyof _SliceMap<S> as Suffix extends string ? `get${_Cap<S>}Init${Capitalize<Suffix>}` : never]: (...args: [...SliceInfoArgs<_SliceMap<S>[Suffix]>, option?: _SliceFetchInitOption<S>]) =>
|
|
40
|
+
[Suffix in keyof _SliceMap<S> as Suffix extends string ? `get${_Cap<S>}Init${Capitalize<Suffix>}` : never]: (...args: [...SliceInfoArgs<_SliceMap<S>[Suffix]>, option?: _SliceFetchInitOption<S>]) => Promise<ServerInit<_RefName<S>, _Light<S>, _Insight<S>, SliceInfoArgs<_SliceMap<S>[Suffix]>, _Filter<S>, _Cap<S>, GetStateObject<_LightWithId<S>>, GetStateObject<_Insight<S>>, _Sort<S>>>;
|
|
41
41
|
};
|
|
42
42
|
export type GetFetchTypeFromSlice<SlceCls extends SliceCls> = SlceCls["srv"]["cnst"] extends ConstantModel ? SlceCls["srv"]["db"] extends DatabaseModel ? SliceListFetch<SlceCls> & SliceInsightFetch<SlceCls> & SliceInitFetch<SlceCls> & SliceGetInitFetch<SlceCls> & RawBaseSliceFetchType<_RefName<SlceCls>, _Input<SlceCls>, _Full<SlceCls>, _Light<SlceCls>, _Cap<SlceCls>, _PurifiedInput<SlceCls>> & AppliedBaseSliceFetchType<_RefName<SlceCls>, _Input<SlceCls>, _Full<SlceCls>, _Cap<SlceCls>, _PurifiedInput<SlceCls>> : never : never;
|
|
43
43
|
type RawBaseSliceFetchType<RefName extends string, Input, Full, Light, _CapitalizedRefName extends string = Capitalize<RefName>, _PurifiedInput = PurifiedModel<Input>> = {
|
|
@@ -49,16 +49,16 @@ type RawBaseSliceFetchType<RefName extends string, Input, Full, Light, _Capitali
|
|
|
49
49
|
} & {
|
|
50
50
|
[K in `update${_CapitalizedRefName}`]: (id: string, input: _PurifiedInput, fetchPolicy?: FetchPolicy) => Promise<Full>;
|
|
51
51
|
} & {
|
|
52
|
-
[K in `remove${_CapitalizedRefName}`]: (id: string, fetchPolicy?: FetchPolicy) => Promise<
|
|
52
|
+
[K in `remove${_CapitalizedRefName}`]: (id: string, fetchPolicy?: FetchPolicy) => Promise<Full>;
|
|
53
53
|
};
|
|
54
54
|
type AppliedBaseSliceFetchType<RefName extends string, Input, Full, _CapitalizedRefName extends string = Capitalize<RefName>, _PurifiedInput = PurifiedModel<Input>> = {
|
|
55
55
|
[K in `view${_CapitalizedRefName}`]: (id: string, option?: FetchPolicy) => Promise<ViewReturn<RefName, Full>>;
|
|
56
56
|
} & {
|
|
57
|
-
[K in `get${_CapitalizedRefName}View`]: (id: string, option?: FetchPolicy) =>
|
|
57
|
+
[K in `get${_CapitalizedRefName}View`]: (id: string, option?: FetchPolicy) => Promise<ServerView<RefName, Full>>;
|
|
58
58
|
} & {
|
|
59
59
|
[K in `edit${_CapitalizedRefName}`]: (id: string, option?: FetchPolicy) => Promise<EditReturn<RefName, Full>>;
|
|
60
60
|
} & {
|
|
61
|
-
[K in `get${_CapitalizedRefName}Edit`]: (id: string, option?: FetchPolicy) =>
|
|
61
|
+
[K in `get${_CapitalizedRefName}Edit`]: (id: string, option?: FetchPolicy) => Promise<ServerEdit<RefName, Full>>;
|
|
62
62
|
} & {
|
|
63
63
|
[K in `add${_CapitalizedRefName}Files`]: (fileList: FileList, parentId?: string, option?: FetchPolicy) => Promise<ProtoFile[]>;
|
|
64
64
|
} & {
|
|
@@ -1,7 +1,20 @@
|
|
|
1
|
+
import type { DatabaseModule, ServiceModule } from "../akanLib.d.ts";
|
|
1
2
|
interface StageTask {
|
|
2
3
|
label: string;
|
|
3
4
|
run: () => Promise<unknown>;
|
|
4
5
|
}
|
|
6
|
+
interface DestroyableUse {
|
|
7
|
+
onDestroy(): Promise<void> | void;
|
|
8
|
+
}
|
|
9
|
+
export interface DiModuleCandidate {
|
|
10
|
+
refName: string;
|
|
11
|
+
module: DatabaseModule | ServiceModule;
|
|
12
|
+
}
|
|
13
|
+
export declare const isDestroyableUse: (value: unknown) => value is DestroyableUse;
|
|
14
|
+
export declare const normalizeServiceRefName: (refName: string) => string;
|
|
15
|
+
export declare const normalizeSignalRefName: (refName: string) => string;
|
|
16
|
+
export declare const normalizeAdaptorRefName: (refName: string) => string;
|
|
17
|
+
export declare const getModuleDependencyRefNames: (mod: DatabaseModule | ServiceModule) => Set<string>;
|
|
5
18
|
/**
|
|
6
19
|
* Run every task in parallel and, if any rejects, throw a single
|
|
7
20
|
* `AggregateError` that enumerates every failing label + cause. This replaces
|