@jskit-ai/kernel 0.1.4
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.md +24 -0
- package/_testable/index.js +4 -0
- package/client/appConfig.js +33 -0
- package/client/componentInteraction.js +51 -0
- package/client/componentInteraction.test.js +111 -0
- package/client/descriptorSections.js +75 -0
- package/client/index.d.ts +70 -0
- package/client/index.js +3 -0
- package/client/logging.js +38 -0
- package/client/moduleBootstrap.js +670 -0
- package/client/moduleBootstrap.test.js +403 -0
- package/client/shellBootstrap.js +233 -0
- package/client/shellBootstrap.test.js +185 -0
- package/client/shellRouting.js +321 -0
- package/client/shellRouting.test.js +113 -0
- package/client/vite/clientBootstrapPlugin.js +259 -0
- package/client/vite/clientBootstrapPlugin.test.js +563 -0
- package/client/vite/index.js +3 -0
- package/internal/node/fileSystem.js +21 -0
- package/internal/node/installedPackageDescriptor.js +104 -0
- package/package.json +43 -0
- package/server/actions/ActionRuntimeServiceProvider.js +309 -0
- package/server/actions/ActionRuntimeServiceProvider.test.js +551 -0
- package/server/actions/index.js +8 -0
- package/server/container/ContainerCoreServiceProvider.js +27 -0
- package/server/container/index.js +10 -0
- package/server/exportPolicy.test.js +68 -0
- package/server/http/HttpFastifyServiceProvider.js +25 -0
- package/server/http/_testable/index.js +2 -0
- package/server/http/index.js +1 -0
- package/server/http/lib/controller.js +183 -0
- package/server/http/lib/controller.test.js +143 -0
- package/server/http/lib/errors.js +12 -0
- package/server/http/lib/httpRuntime.js +82 -0
- package/server/http/lib/index.js +18 -0
- package/server/http/lib/kernel.js +15 -0
- package/server/http/lib/kernel.test.js +880 -0
- package/server/http/lib/middlewareRuntime.js +149 -0
- package/server/http/lib/requestActionExecutor.js +258 -0
- package/server/http/lib/requestScope.js +59 -0
- package/server/http/lib/routeRegistration.js +165 -0
- package/server/http/lib/routeSupport.js +45 -0
- package/server/http/lib/routeValidator.js +469 -0
- package/server/http/lib/routeValidator.test.js +474 -0
- package/server/http/lib/router.js +206 -0
- package/server/kernel/KernelCoreServiceProvider.js +27 -0
- package/server/kernel/index.js +10 -0
- package/server/platform/PlatformServerRuntimeServiceProvider.js +30 -0
- package/server/platform/index.js +5 -0
- package/server/platform/providerRuntime/descriptorCatalog.js +170 -0
- package/server/platform/providerRuntime/helpers.js +45 -0
- package/server/platform/providerRuntime/lockfile.js +27 -0
- package/server/platform/providerRuntime/providerLoader.js +283 -0
- package/server/platform/providerRuntime.js +142 -0
- package/server/platform/providerRuntime.test.js +217 -0
- package/server/platform/runtime.js +40 -0
- package/server/platform/surfaceRuntime.js +150 -0
- package/server/platform/surfaceRuntime.test.js +136 -0
- package/server/registries/actionSurfaceSourceRegistry.js +150 -0
- package/server/registries/bootstrapPayloadContributorRegistry.js +41 -0
- package/server/registries/domainEventListenerRegistry.js +61 -0
- package/server/registries/index.js +36 -0
- package/server/registries/primitives.js +63 -0
- package/server/registries/routeVisibilityResolverRegistry.js +87 -0
- package/server/registries/serviceRegistrationRegistry.js +431 -0
- package/server/runtime/ServerRuntimeCoreServiceProvider.js +65 -0
- package/server/runtime/ServerRuntimeCoreServiceProvider.test.js +53 -0
- package/server/runtime/apiRoutePolicyParity.test.js +109 -0
- package/server/runtime/apiRouteRegistration.js +65 -0
- package/server/runtime/bootBootstrapRoutes.js +46 -0
- package/server/runtime/bootBootstrapRoutes.test.js +79 -0
- package/server/runtime/bootstrapContributors.test.js +114 -0
- package/server/runtime/canonicalJson.js +74 -0
- package/server/runtime/composition.js +142 -0
- package/server/runtime/domainEvents.test.js +114 -0
- package/server/runtime/domainRules.js +50 -0
- package/server/runtime/domainRules.test.js +87 -0
- package/server/runtime/entityChangeEvents.js +182 -0
- package/server/runtime/entityChangeEvents.test.js +211 -0
- package/server/runtime/errors.js +68 -0
- package/server/runtime/errors.test.js +73 -0
- package/server/runtime/fastifyBootstrap.js +372 -0
- package/server/runtime/fastifyBootstrap.test.js +194 -0
- package/server/runtime/index.js +6 -0
- package/server/runtime/integers.js +13 -0
- package/server/runtime/moduleConfig.js +269 -0
- package/server/runtime/moduleConfig.test.js +141 -0
- package/server/runtime/pagination.js +13 -0
- package/server/runtime/realtimeNormalization.js +21 -0
- package/server/runtime/requestUrl.js +38 -0
- package/server/runtime/routeUtils.js +20 -0
- package/server/runtime/runtimeAssembly.js +113 -0
- package/server/runtime/runtimeKernel.js +55 -0
- package/server/runtime/securityAudit.js +269 -0
- package/server/runtime/securityAudit.test.js +41 -0
- package/server/runtime/serviceAuthorization.js +113 -0
- package/server/runtime/serviceAuthorization.test.js +100 -0
- package/server/runtime/serviceRegistration.test.js +197 -0
- package/server/support/SupportCoreServiceProvider.js +25 -0
- package/server/support/appConfig.js +37 -0
- package/server/support/appConfig.test.js +94 -0
- package/server/support/defaultMissingHandler.js +7 -0
- package/server/support/index.js +2 -0
- package/server/support/routePolicyConfig.js +51 -0
- package/server/support/symlinkSafeRequire.js +78 -0
- package/server/support/symlinkSafeRequire.test.js +27 -0
- package/server/surface/SurfaceRoutingServiceProvider.js +27 -0
- package/server/surface/index.js +19 -0
- package/shared/actions/actionContributorHelpers.js +34 -0
- package/shared/actions/actionContributorHelpers.test.js +16 -0
- package/shared/actions/actionDefinitions.js +488 -0
- package/shared/actions/actionDefinitions.test.js +212 -0
- package/shared/actions/audit.js +7 -0
- package/shared/actions/executionContext.js +97 -0
- package/shared/actions/executionContext.test.js +66 -0
- package/shared/actions/idempotency.js +62 -0
- package/shared/actions/index.js +2 -0
- package/shared/actions/observability.js +10 -0
- package/shared/actions/pipeline.js +287 -0
- package/shared/actions/policies.js +342 -0
- package/shared/actions/policies.test.js +233 -0
- package/shared/actions/registry.js +187 -0
- package/shared/actions/registry.test.js +381 -0
- package/shared/actions/requestMeta.js +36 -0
- package/shared/actions/textNormalization.js +3 -0
- package/shared/actions/withActionDefaults.js +34 -0
- package/shared/index.js +2 -0
- package/shared/runtime/application.js +323 -0
- package/shared/runtime/container.js +261 -0
- package/shared/runtime/containerErrors.js +22 -0
- package/shared/runtime/index.js +18 -0
- package/shared/runtime/kernelErrors.js +20 -0
- package/shared/runtime/serviceProvider.js +13 -0
- package/shared/support/formatDateTime.js +10 -0
- package/shared/support/formatDateTime.test.js +15 -0
- package/shared/support/index.js +14 -0
- package/shared/support/linkPath.js +67 -0
- package/shared/support/linkPath.test.js +35 -0
- package/shared/support/normalize.js +116 -0
- package/shared/support/normalize.test.js +48 -0
- package/shared/support/packageDescriptor.test.js +121 -0
- package/shared/support/permissions.js +50 -0
- package/shared/support/pickOwnProperties.js +17 -0
- package/shared/support/pickOwnProperties.test.js +25 -0
- package/shared/support/policies.js +11 -0
- package/shared/support/queryPath.js +33 -0
- package/shared/support/queryPath.test.js +19 -0
- package/shared/support/queryResilience.js +34 -0
- package/shared/support/queryResilience.test.js +33 -0
- package/shared/support/returnToPath.js +153 -0
- package/shared/support/returnToPath.test.js +123 -0
- package/shared/support/sorting.js +15 -0
- package/shared/support/tokens.js +23 -0
- package/shared/support/tokens.test.js +17 -0
- package/shared/support/visibility.js +56 -0
- package/shared/support/visibility.test.js +45 -0
- package/shared/surface/apiPaths.js +84 -0
- package/shared/surface/escapeRegExp.js +5 -0
- package/shared/surface/index.js +6 -0
- package/shared/surface/paths.js +273 -0
- package/shared/surface/registry.js +135 -0
- package/shared/surface/registry.test.js +44 -0
- package/shared/surface/runtime.js +357 -0
- package/shared/surface/runtime.test.js +319 -0
- package/shared/validators/createCursorListValidator.js +42 -0
- package/shared/validators/createCursorListValidator.test.js +34 -0
- package/shared/validators/cursorPaginationQueryValidator.js +31 -0
- package/shared/validators/cursorPaginationQueryValidator.test.js +21 -0
- package/shared/validators/index.js +12 -0
- package/shared/validators/inputNormalization.js +13 -0
- package/shared/validators/mergeObjectSchemas.js +31 -0
- package/shared/validators/mergeObjectSchemas.test.js +67 -0
- package/shared/validators/mergeValidators.js +89 -0
- package/shared/validators/mergeValidators.test.js +116 -0
- package/shared/validators/nestValidator.js +53 -0
- package/shared/validators/nestValidator.test.js +60 -0
- package/shared/validators/recordIdParamsValidator.js +36 -0
- package/shared/validators/recordIdParamsValidator.test.js +20 -0
- package/shared/validators/resourceRequiredMetadata.js +41 -0
- package/shared/validators/resourceRequiredMetadata.test.js +49 -0
- package/test/barrelExposure.test.js +106 -0
- package/test/dynamicImportPolicy.test.js +89 -0
- package/test/exportsContract.test.js +168 -0
- package/test/routeInputContractGuard.test.js +78 -0
- package/test/surfaceIndependence.test.js +109 -0
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jskit-ai/kernel",
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"dependencies": {
|
|
6
|
+
"typebox": "^1.0.81"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"test": "node --test"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
"./_testable": "./_testable/index.js",
|
|
13
|
+
"./client": {
|
|
14
|
+
"types": "./client/index.d.ts",
|
|
15
|
+
"default": "./client/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./client/moduleBootstrap": "./client/moduleBootstrap.js",
|
|
18
|
+
"./client/vite": "./client/vite/index.js",
|
|
19
|
+
"./server/actions": "./server/actions/index.js",
|
|
20
|
+
"./server/http": "./server/http/index.js",
|
|
21
|
+
"./server/platform": "./server/platform/index.js",
|
|
22
|
+
"./server/runtime": "./server/runtime/index.js",
|
|
23
|
+
"./server/runtime/errors": "./server/runtime/errors.js",
|
|
24
|
+
"./server/runtime/requestUrl": "./server/runtime/requestUrl.js",
|
|
25
|
+
"./server/support": "./server/support/index.js",
|
|
26
|
+
"./shared": "./shared/index.js",
|
|
27
|
+
"./shared/actions": "./shared/actions/index.js",
|
|
28
|
+
"./shared/actions/actionContributorHelpers": "./shared/actions/actionContributorHelpers.js",
|
|
29
|
+
"./shared/actions/textNormalization": "./shared/actions/textNormalization.js",
|
|
30
|
+
"./shared/validators": "./shared/validators/index.js",
|
|
31
|
+
"./shared/validators/inputNormalization": "./shared/validators/inputNormalization.js",
|
|
32
|
+
"./shared/support": "./shared/support/index.js",
|
|
33
|
+
"./shared/support/tokens": "./shared/support/tokens.js",
|
|
34
|
+
"./shared/support/normalize": "./shared/support/normalize.js",
|
|
35
|
+
"./shared/support/returnToPath": "./shared/support/returnToPath.js",
|
|
36
|
+
"./shared/support/visibility": "./shared/support/visibility.js",
|
|
37
|
+
"./shared/support/linkPath": "./shared/support/linkPath.js",
|
|
38
|
+
"./shared/surface": "./shared/surface/index.js",
|
|
39
|
+
"./shared/surface/paths": "./shared/surface/paths.js",
|
|
40
|
+
"./shared/surface/runtime": "./shared/surface/runtime.js",
|
|
41
|
+
"./shared/surface/registry": "./shared/surface/registry.js"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { normalizeActionDomain } from "../../shared/actions/actionDefinitions.js";
|
|
2
|
+
import { createNoopAuditAdapter } from "../../shared/actions/audit.js";
|
|
3
|
+
import { createNoopIdempotencyAdapter } from "../../shared/actions/idempotency.js";
|
|
4
|
+
import { createNoopObservabilityAdapter } from "../../shared/actions/observability.js";
|
|
5
|
+
import { createActionRegistry } from "../../shared/actions/registry.js";
|
|
6
|
+
import { createSurfaceRuntime } from "../../shared/surface/runtime.js";
|
|
7
|
+
import { normalizeObject } from "../../shared/support/normalize.js";
|
|
8
|
+
import { KERNEL_TOKENS, isContainerToken } from "../../shared/support/tokens.js";
|
|
9
|
+
import { installServiceRegistrationApi } from "../registries/serviceRegistrationRegistry.js";
|
|
10
|
+
import {
|
|
11
|
+
ensureActionSurfaceSourceRegistry,
|
|
12
|
+
resolveActionSurfaceSourceIds
|
|
13
|
+
} from "../registries/actionSurfaceSourceRegistry.js";
|
|
14
|
+
import {
|
|
15
|
+
normalizeContributorEntry,
|
|
16
|
+
normalizeNestedEntries,
|
|
17
|
+
registerTaggedSingleton,
|
|
18
|
+
resolveTaggedEntries as resolveRegistryTaggedEntries
|
|
19
|
+
} from "../registries/primitives.js";
|
|
20
|
+
|
|
21
|
+
const ACTION_RUNTIME_API = Object.freeze({
|
|
22
|
+
createActionRegistry,
|
|
23
|
+
createNoopIdempotencyAdapter,
|
|
24
|
+
createNoopAuditAdapter,
|
|
25
|
+
createNoopObservabilityAdapter
|
|
26
|
+
});
|
|
27
|
+
const ACTION_RUNTIME_CONTRIBUTOR_TAG = Symbol.for("jskit.runtime.actions.contributors");
|
|
28
|
+
const ACTION_CONTEXT_CONTRIBUTOR_TAG = Symbol.for("jskit.runtime.actions.contextContributors");
|
|
29
|
+
const LOGGER_TOKEN = Symbol.for("jskit.logger");
|
|
30
|
+
let ACTION_RUNTIME_CONTRIBUTOR_INDEX = 0;
|
|
31
|
+
|
|
32
|
+
function createSurfaceRuntimeFromAppConfig(scope) {
|
|
33
|
+
if (!scope || typeof scope.has !== "function" || typeof scope.make !== "function") {
|
|
34
|
+
throw new Error("Surface runtime registration requires scope.has()/make().");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!scope.has("appConfig")) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
"ActionRuntimeServiceProvider requires appConfig.surfaceDefinitions when KERNEL_TOKENS.SurfaceRuntime is not registered."
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const appConfig = normalizeObject(scope.make("appConfig"));
|
|
44
|
+
const surfaceDefinitions = normalizeObject(appConfig.surfaceDefinitions);
|
|
45
|
+
if (Object.keys(surfaceDefinitions).length < 1) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
"ActionRuntimeServiceProvider requires appConfig.surfaceDefinitions when KERNEL_TOKENS.SurfaceRuntime is not registered."
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return createSurfaceRuntime({
|
|
52
|
+
allMode: appConfig.surfaceModeAll,
|
|
53
|
+
surfaces: surfaceDefinitions,
|
|
54
|
+
defaultSurfaceId: appConfig.surfaceDefaultId
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function normalizeDependencyMap(value, { context = "action dependencies" } = {}) {
|
|
59
|
+
const source = normalizeObject(value);
|
|
60
|
+
const normalized = {};
|
|
61
|
+
|
|
62
|
+
for (const [key, token] of Object.entries(source)) {
|
|
63
|
+
const dependencyName = String(key || "").trim();
|
|
64
|
+
if (!dependencyName) {
|
|
65
|
+
throw new Error(`${context} keys must be non-empty strings.`);
|
|
66
|
+
}
|
|
67
|
+
if (!isContainerToken(token)) {
|
|
68
|
+
throw new Error(`${context}.${dependencyName} must be a valid container token.`);
|
|
69
|
+
}
|
|
70
|
+
normalized[dependencyName] = token;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return Object.freeze(normalized);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function resolveActionContributors(scope) {
|
|
77
|
+
return resolveRegistryTaggedEntries(scope, ACTION_RUNTIME_CONTRIBUTOR_TAG).filter(
|
|
78
|
+
(entry) => entry && typeof entry === "object" && !Array.isArray(entry)
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function resolveActionContextContributors(scope) {
|
|
83
|
+
return resolveRegistryTaggedEntries(scope, ACTION_CONTEXT_CONTRIBUTOR_TAG)
|
|
84
|
+
.map((entry) => normalizeContributorEntry(entry))
|
|
85
|
+
.filter(Boolean);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function createActionExecutor(actionRegistry) {
|
|
89
|
+
return Object.freeze({
|
|
90
|
+
execute(payload) {
|
|
91
|
+
const source = normalizeObject(payload);
|
|
92
|
+
return actionRegistry.execute({
|
|
93
|
+
actionId: source.actionId,
|
|
94
|
+
version: source.version == null ? null : source.version,
|
|
95
|
+
input: normalizeObject(source.input),
|
|
96
|
+
context: normalizeObject(source.context),
|
|
97
|
+
deps: normalizeObject(source.deps)
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
executeStream(payload) {
|
|
101
|
+
const source = normalizeObject(payload);
|
|
102
|
+
return actionRegistry.executeStream({
|
|
103
|
+
actionId: source.actionId,
|
|
104
|
+
version: source.version == null ? null : source.version,
|
|
105
|
+
input: normalizeObject(source.input),
|
|
106
|
+
context: normalizeObject(source.context),
|
|
107
|
+
deps: normalizeObject(source.deps)
|
|
108
|
+
});
|
|
109
|
+
},
|
|
110
|
+
listDefinitions() {
|
|
111
|
+
return actionRegistry.listDefinitions();
|
|
112
|
+
},
|
|
113
|
+
getDefinition(actionId, version = null) {
|
|
114
|
+
return actionRegistry.getDefinition(actionId, version);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function createActionContributorToken() {
|
|
120
|
+
ACTION_RUNTIME_CONTRIBUTOR_INDEX += 1;
|
|
121
|
+
return Symbol(`jskit.runtime.actions.contributor.${ACTION_RUNTIME_CONTRIBUTOR_INDEX}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function materializeDependencies(scope, dependencyMap, { context = "action.dependencies" } = {}) {
|
|
125
|
+
const normalizedMap = normalizeDependencyMap(dependencyMap, { context });
|
|
126
|
+
const resolved = {};
|
|
127
|
+
for (const [name, token] of Object.entries(normalizedMap)) {
|
|
128
|
+
resolved[name] = scope.make(token);
|
|
129
|
+
}
|
|
130
|
+
return Object.freeze(resolved);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function materializeAction(scope, actionDefinition) {
|
|
134
|
+
const source = normalizeObject(actionDefinition);
|
|
135
|
+
const materialized = { ...source };
|
|
136
|
+
const actionDependencies = materializeDependencies(scope, source.dependencies, {
|
|
137
|
+
context: `action ${String(source.id || "<unknown>")}.dependencies`
|
|
138
|
+
});
|
|
139
|
+
const resolvedDependencies = actionDependencies;
|
|
140
|
+
|
|
141
|
+
if (Object.hasOwn(source, "surfaces") && Object.hasOwn(source, "surfacesFrom")) {
|
|
142
|
+
throw new Error(`Action ${String(source.id || "<unknown>")} cannot define both surfaces and surfacesFrom.`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
delete materialized.dependencies;
|
|
146
|
+
delete materialized.surfacesFrom;
|
|
147
|
+
|
|
148
|
+
if (Object.hasOwn(source, "surfacesFrom")) {
|
|
149
|
+
const resolvedSurfaces = resolveActionSurfaceSourceIds(scope, source.surfacesFrom, {
|
|
150
|
+
context: `action ${String(source.id || "<unknown>")}.surfacesFrom`
|
|
151
|
+
});
|
|
152
|
+
if (resolvedSurfaces.length < 1) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
materialized.surfaces = resolvedSurfaces;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (typeof source.execute === "function") {
|
|
159
|
+
materialized.execute = async function executeMaterializedAction(input, context, runtimeDependencies = {}) {
|
|
160
|
+
const runtimeDeps = normalizeObject(runtimeDependencies);
|
|
161
|
+
const mergedDependencies = Object.freeze({
|
|
162
|
+
...resolvedDependencies,
|
|
163
|
+
...runtimeDeps
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
return source.execute(input, context, mergedDependencies);
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return Object.freeze(materialized);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function registerActionDefinition(app, actionSpec, { context = "app.action" } = {}) {
|
|
174
|
+
const token = createActionContributorToken();
|
|
175
|
+
registerTaggedSingleton(
|
|
176
|
+
app,
|
|
177
|
+
token,
|
|
178
|
+
(scope) => {
|
|
179
|
+
const action = materializeAction(scope, actionSpec.action);
|
|
180
|
+
if (!action) {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
contributorId: actionSpec.contributorId,
|
|
186
|
+
domain: action.domain,
|
|
187
|
+
actions: Object.freeze([action])
|
|
188
|
+
};
|
|
189
|
+
},
|
|
190
|
+
ACTION_RUNTIME_CONTRIBUTOR_TAG,
|
|
191
|
+
{ context }
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function normalizeSingleActionRegistration(actionDefinition, { context = "app.action" } = {}) {
|
|
196
|
+
const source = normalizeObject(actionDefinition);
|
|
197
|
+
const actionId = String(source.id || "").trim();
|
|
198
|
+
const contributorId = String(source.contributorId || "").trim() || (actionId ? `action.${actionId}` : "");
|
|
199
|
+
if (!contributorId) {
|
|
200
|
+
throw new Error(`${context} requires action.id or action.contributorId.`);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const normalizedAction = {
|
|
204
|
+
...source
|
|
205
|
+
};
|
|
206
|
+
delete normalizedAction.contributorId;
|
|
207
|
+
normalizedAction.domain = normalizeActionDomain(normalizedAction.domain, {
|
|
208
|
+
context: `${context} domain`
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
return Object.freeze({
|
|
212
|
+
contributorId,
|
|
213
|
+
action: Object.freeze(normalizedAction)
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function installActionRegistrationApi(app) {
|
|
218
|
+
if (typeof app.action === "function" && typeof app.actions === "function") {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const registerActions = function registerActions(actionDefinitions = []) {
|
|
223
|
+
if (!Array.isArray(actionDefinitions)) {
|
|
224
|
+
throw new Error("app.actions requires an array of action definitions.");
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const entries = normalizeNestedEntries(actionDefinitions);
|
|
228
|
+
for (const entry of entries) {
|
|
229
|
+
this.action(entry);
|
|
230
|
+
}
|
|
231
|
+
return this;
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
const registerAction = function registerAction(actionDefinition = {}) {
|
|
235
|
+
const actionSpec = normalizeSingleActionRegistration(actionDefinition, {
|
|
236
|
+
context: "app.action"
|
|
237
|
+
});
|
|
238
|
+
registerActionDefinition(this, actionSpec, { context: "app.action" });
|
|
239
|
+
return this;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
Object.defineProperty(app, "actions", {
|
|
243
|
+
configurable: true,
|
|
244
|
+
writable: true,
|
|
245
|
+
value: registerActions
|
|
246
|
+
});
|
|
247
|
+
Object.defineProperty(app, "action", {
|
|
248
|
+
configurable: true,
|
|
249
|
+
writable: true,
|
|
250
|
+
value: registerAction
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function registerActionContextContributor(app, token, factory) {
|
|
255
|
+
registerTaggedSingleton(
|
|
256
|
+
app,
|
|
257
|
+
token,
|
|
258
|
+
factory,
|
|
259
|
+
ACTION_CONTEXT_CONTRIBUTOR_TAG,
|
|
260
|
+
{ context: "registerActionContextContributor" }
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
class ActionRuntimeServiceProvider {
|
|
265
|
+
static id = "runtime.actions";
|
|
266
|
+
|
|
267
|
+
register(app) {
|
|
268
|
+
if (!app || typeof app.singleton !== "function" || typeof app.has !== "function" || typeof app.tag !== "function") {
|
|
269
|
+
throw new Error("ActionRuntimeServiceProvider requires application singleton()/has()/tag().");
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
installActionRegistrationApi(app);
|
|
273
|
+
ensureActionSurfaceSourceRegistry(app);
|
|
274
|
+
installServiceRegistrationApi(app);
|
|
275
|
+
|
|
276
|
+
if (!app.has(KERNEL_TOKENS.SurfaceRuntime)) {
|
|
277
|
+
app.singleton(KERNEL_TOKENS.SurfaceRuntime, (scope) => createSurfaceRuntimeFromAppConfig(scope));
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
app.singleton("runtime.actions", () => ACTION_RUNTIME_API);
|
|
281
|
+
|
|
282
|
+
if (!app.has("actionRegistry")) {
|
|
283
|
+
app.singleton("actionRegistry", (scope) => {
|
|
284
|
+
return createActionRegistry({
|
|
285
|
+
contributors: resolveActionContributors(scope),
|
|
286
|
+
idempotencyAdapter: createNoopIdempotencyAdapter(),
|
|
287
|
+
auditAdapter: createNoopAuditAdapter(),
|
|
288
|
+
observabilityAdapter: createNoopObservabilityAdapter(),
|
|
289
|
+
logger: scope.has(LOGGER_TOKEN) ? scope.make(LOGGER_TOKEN) : console
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (!app.has("actionExecutor")) {
|
|
295
|
+
app.singleton("actionExecutor", (scope) => createActionExecutor(scope.make("actionRegistry")));
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
boot() {}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export {
|
|
303
|
+
ACTION_RUNTIME_CONTRIBUTOR_TAG,
|
|
304
|
+
ACTION_CONTEXT_CONTRIBUTOR_TAG,
|
|
305
|
+
resolveActionContributors,
|
|
306
|
+
resolveActionContextContributors,
|
|
307
|
+
registerActionContextContributor,
|
|
308
|
+
ActionRuntimeServiceProvider
|
|
309
|
+
};
|