@ankhorage/runtime 0.3.0 → 1.1.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/CHANGELOG.md +12 -0
- package/README.md +2 -2
- package/dist/RuntimeRenderer.d.ts +4 -1
- package/dist/RuntimeRenderer.d.ts.map +1 -1
- package/dist/RuntimeRenderer.js +32 -13
- package/dist/RuntimeRenderer.js.map +1 -1
- package/dist/RuntimeRendererConfig.d.ts +4 -1
- package/dist/RuntimeRendererConfig.d.ts.map +1 -1
- package/dist/RuntimeRendererConfig.js +2 -0
- package/dist/RuntimeRendererConfig.js.map +1 -1
- package/dist/RuntimeScreen.d.ts.map +1 -1
- package/dist/RuntimeScreen.js +5 -43
- package/dist/RuntimeScreen.js.map +1 -1
- package/dist/index.d.ts +2 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/readme-usage.js +1 -1
- package/dist/readme-usage.js.map +1 -1
- package/dist/runtimeDataSourceOperations.d.ts +3 -1
- package/dist/runtimeDataSourceOperations.d.ts.map +1 -1
- package/dist/runtimeDataSourceOperations.js +31 -26
- package/dist/runtimeDataSourceOperations.js.map +1 -1
- package/dist/runtimeDatabaseOperationExecutor.d.ts +9 -0
- package/dist/runtimeDatabaseOperationExecutor.d.ts.map +1 -0
- package/dist/runtimeDatabaseOperationExecutor.js +228 -0
- package/dist/runtimeDatabaseOperationExecutor.js.map +1 -0
- package/dist/runtimeMedia.d.ts +13 -0
- package/dist/runtimeMedia.d.ts.map +1 -0
- package/dist/runtimeMedia.js +80 -0
- package/dist/runtimeMedia.js.map +1 -0
- package/dist/runtimeMediaCache.d.ts +8 -0
- package/dist/runtimeMediaCache.d.ts.map +1 -0
- package/dist/runtimeMediaCache.js +14 -0
- package/dist/runtimeMediaCache.js.map +1 -0
- package/dist/runtimeScreenLoaders.d.ts +1 -2
- package/dist/runtimeScreenLoaders.d.ts.map +1 -1
- package/dist/runtimeScreenLoaders.js +1 -4
- package/dist/runtimeScreenLoaders.js.map +1 -1
- package/dist/useRuntimeMediaProps.d.ts +9 -0
- package/dist/useRuntimeMediaProps.d.ts.map +1 -0
- package/dist/useRuntimeMediaProps.js +61 -0
- package/dist/useRuntimeMediaProps.js.map +1 -0
- package/package.json +5 -4
- package/paradox/badges/npm.svg +3 -3
- package/paradox/components.md +5 -3
- package/paradox/diagrams/architecture-overview.mmd +23 -9
- package/paradox/diagrams/export-graph.mmd +14 -47
- package/paradox/diagrams/module-relationships.mmd +17 -7
- package/paradox/diagrams/sequences/runtime-screen.mmd +0 -3
- package/paradox/exports.json +136 -496
- package/paradox/exports.md +136 -278
- package/paradox/index.html +991 -1119
- package/paradox/paradox.json +1405 -1254
- package/dist/runtimeApiLoaders.d.ts +0 -35
- package/dist/runtimeApiLoaders.d.ts.map +0 -1
- package/dist/runtimeApiLoaders.js +0 -218
- package/dist/runtimeApiLoaders.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimeDataSourceOperations.d.ts","sourceRoot":"","sources":["../src/runtimeDataSourceOperations.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtimeDataSourceOperations.d.ts","sourceRoot":"","sources":["../src/runtimeDataSourceOperations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsC,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,KAAK,EAAE,8BAA8B,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAGjG,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,mBAAmB,CAAC;AAGzE,MAAM,WAAW,yCAAyC;IACxD,QAAQ,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,8BAA8B,CAAC;IAC7D,QAAQ,CAAC,gBAAgB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;CACjE;AAED,wBAAgB,wCAAwC,CACtD,OAAO,EAAE,yCAAyC,GACjD,+BAA+B,CAsCjC"}
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import { testEndpoint } from '@ankhorage/data-sources';
|
|
2
|
+
import { executeRuntimeDatabaseOperation } from './runtimeDatabaseOperationExecutor';
|
|
2
3
|
export function createRuntimeDataSourceOperationExecutor(options) {
|
|
3
4
|
return async ({ dataSource, endpoint, input, operation }) => {
|
|
4
5
|
if (endpoint === undefined) {
|
|
5
|
-
return
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
6
|
+
return missingEndpoint(operation.dataSourceId, operation.endpointId, operation.operationId);
|
|
7
|
+
}
|
|
8
|
+
const operationConfig = endpoint.operations[operation.operationId];
|
|
9
|
+
if (operationConfig === undefined) {
|
|
10
|
+
return missingOperation(operation.dataSourceId, endpoint.id, operation.operationId);
|
|
11
11
|
}
|
|
12
12
|
const values = asBindingValueRecord(input);
|
|
13
13
|
if (input !== undefined && values === undefined) {
|
|
14
|
-
return
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
return invalidInput(operation.dataSourceId, endpoint.id, operation.operationId);
|
|
15
|
+
}
|
|
16
|
+
if (operationConfig.protocol === 'database') {
|
|
17
|
+
return executeRuntimeDatabaseOperation({
|
|
18
|
+
dataSource,
|
|
19
|
+
operation: operationConfig,
|
|
20
|
+
input: values,
|
|
21
|
+
databaseAdapters: options.databaseAdapters,
|
|
22
|
+
});
|
|
20
23
|
}
|
|
21
24
|
const result = await testEndpoint({
|
|
22
25
|
credentialResolver: options.credentialResolver,
|
|
@@ -26,28 +29,30 @@ export function createRuntimeDataSourceOperationExecutor(options) {
|
|
|
26
29
|
operationId: operation.operationId,
|
|
27
30
|
values,
|
|
28
31
|
});
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
diagnostics: result.diagnostics,
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
return {
|
|
36
|
-
ok: true,
|
|
37
|
-
data: result.data ?? null,
|
|
38
|
-
diagnostics: result.diagnostics,
|
|
39
|
-
};
|
|
32
|
+
return result.ok
|
|
33
|
+
? { ok: true, data: result.data ?? null, diagnostics: result.diagnostics }
|
|
34
|
+
: { ok: false, diagnostics: result.diagnostics };
|
|
40
35
|
};
|
|
41
36
|
}
|
|
42
|
-
function
|
|
43
|
-
return {
|
|
44
|
-
|
|
37
|
+
function missingEndpoint(dataSourceId, endpointId, operationId) {
|
|
38
|
+
return failure(dataSourceId, endpointId, operationId, 'missing-endpoint', `Endpoint '${endpointId ?? '<default>'}' could not be found.`);
|
|
39
|
+
}
|
|
40
|
+
function missingOperation(dataSourceId, endpointId, operationId) {
|
|
41
|
+
return failure(dataSourceId, endpointId, operationId, 'missing-operation', `Operation '${operationId}' could not be found.`);
|
|
42
|
+
}
|
|
43
|
+
function invalidInput(dataSourceId, endpointId, operationId) {
|
|
44
|
+
return failure(dataSourceId, endpointId, operationId, 'invalid-config', 'Operation input must resolve to an object.');
|
|
45
|
+
}
|
|
46
|
+
function failure(dataSourceId, endpointId, operationId, code, message) {
|
|
47
|
+
const diagnostic = {
|
|
48
|
+
code,
|
|
45
49
|
dataSourceId,
|
|
46
50
|
endpointId,
|
|
47
51
|
operationId,
|
|
48
52
|
message,
|
|
49
53
|
severity: 'error',
|
|
50
54
|
};
|
|
55
|
+
return { ok: false, diagnostics: [diagnostic] };
|
|
51
56
|
}
|
|
52
57
|
function asBindingValueRecord(value) {
|
|
53
58
|
return isBindingValueRecord(value) ? value : undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimeDataSourceOperations.js","sourceRoot":"","sources":["../src/runtimeDataSourceOperations.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"runtimeDataSourceOperations.js","sourceRoot":"","sources":["../src/runtimeDataSourceOperations.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BindingValue, DataSourceDiagnostic, DbAdapter } from '@ankhorage/contracts';\nimport type { EndpointTestCredentialResolver, EndpointTestFetch } from '@ankhorage/data-sources';\nimport { testEndpoint } from '@ankhorage/data-sources';\n\nimport type { RuntimeBindingOperationExecutor } from './runtimeBindings';\nimport { executeRuntimeDatabaseOperation } from './runtimeDatabaseOperationExecutor';\n\nexport interface RuntimeDataSourceOperationExecutorOptions {\n readonly fetch?: EndpointTestFetch;\n readonly credentialResolver?: EndpointTestCredentialResolver;\n readonly databaseAdapters?: Readonly<Record<string, DbAdapter>>;\n}\n\nexport function createRuntimeDataSourceOperationExecutor(\n options: RuntimeDataSourceOperationExecutorOptions,\n): RuntimeBindingOperationExecutor {\n return async ({ dataSource, endpoint, input, operation }) => {\n if (endpoint === undefined) {\n return missingEndpoint(operation.dataSourceId, operation.endpointId, operation.operationId);\n }\n\n const operationConfig = endpoint.operations[operation.operationId];\n if (operationConfig === undefined) {\n return missingOperation(operation.dataSourceId, endpoint.id, operation.operationId);\n }\n\n const values = asBindingValueRecord(input);\n if (input !== undefined && values === undefined) {\n return invalidInput(operation.dataSourceId, endpoint.id, operation.operationId);\n }\n\n if (operationConfig.protocol === 'database') {\n return executeRuntimeDatabaseOperation({\n dataSource,\n operation: operationConfig,\n input: values,\n databaseAdapters: options.databaseAdapters,\n });\n }\n\n const result = await testEndpoint({\n credentialResolver: options.credentialResolver,\n dataSource,\n endpointId: endpoint.id,\n fetch: options.fetch,\n operationId: operation.operationId,\n values,\n });\n\n return result.ok\n ? { ok: true, data: result.data ?? null, diagnostics: result.diagnostics }\n : { ok: false, diagnostics: result.diagnostics };\n };\n}\n\nfunction missingEndpoint(\n dataSourceId: string,\n endpointId: string | undefined,\n operationId: string,\n) {\n return failure(\n dataSourceId,\n endpointId,\n operationId,\n 'missing-endpoint',\n `Endpoint '${endpointId ?? '<default>'}' could not be found.`,\n );\n}\n\nfunction missingOperation(dataSourceId: string, endpointId: string, operationId: string) {\n return failure(\n dataSourceId,\n endpointId,\n operationId,\n 'missing-operation',\n `Operation '${operationId}' could not be found.`,\n );\n}\n\nfunction invalidInput(dataSourceId: string, endpointId: string, operationId: string) {\n return failure(\n dataSourceId,\n endpointId,\n operationId,\n 'invalid-config',\n 'Operation input must resolve to an object.',\n );\n}\n\nfunction failure(\n dataSourceId: string,\n endpointId: string | undefined,\n operationId: string,\n code: string,\n message: string,\n) {\n const diagnostic: DataSourceDiagnostic = {\n code,\n dataSourceId,\n endpointId,\n operationId,\n message,\n severity: 'error',\n };\n return { ok: false as const, diagnostics: [diagnostic] };\n}\n\nfunction asBindingValueRecord(\n value: BindingValue | undefined,\n): Readonly<Record<string, BindingValue>> | undefined {\n return isBindingValueRecord(value) ? value : undefined;\n}\n\nfunction isBindingValueRecord(\n value: BindingValue | undefined,\n): value is Readonly<Record<string, BindingValue>> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BindingValue, DataOperationConfig, DataSourceConfig, DbAdapter } from '@ankhorage/contracts';
|
|
2
|
+
import type { RuntimeBindingOperationExecutionResult } from './runtimeBindings';
|
|
3
|
+
export declare function executeRuntimeDatabaseOperation(args: {
|
|
4
|
+
readonly dataSource: DataSourceConfig;
|
|
5
|
+
readonly operation: DataOperationConfig;
|
|
6
|
+
readonly input: Readonly<Record<string, BindingValue>> | undefined;
|
|
7
|
+
readonly databaseAdapters: Readonly<Record<string, DbAdapter>> | undefined;
|
|
8
|
+
}): Promise<RuntimeBindingOperationExecutionResult>;
|
|
9
|
+
//# sourceMappingURL=runtimeDatabaseOperationExecutor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeDatabaseOperationExecutor.d.ts","sourceRoot":"","sources":["../src/runtimeDatabaseOperationExecutor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAEhB,SAAS,EAGV,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,sCAAsC,EAAE,MAAM,mBAAmB,CAAC;AAEhF,wBAAsB,+BAA+B,CAAC,IAAI,EAAE;IAC1D,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,GAAG,SAAS,CAAC;IACnE,QAAQ,CAAC,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC;CAC5E,GAAG,OAAO,CAAC,sCAAsC,CAAC,CA0BlD"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
export async function executeRuntimeDatabaseOperation(args) {
|
|
2
|
+
const plan = resolveOperationPlan(args.dataSource, args.operation);
|
|
3
|
+
if (!plan.ok)
|
|
4
|
+
return plan.result;
|
|
5
|
+
const adapter = args.databaseAdapters?.[plan.adapterId];
|
|
6
|
+
if (adapter === undefined) {
|
|
7
|
+
return failure(args, 'missing-adapter', `Database adapter '${plan.adapterId}' is not available.`);
|
|
8
|
+
}
|
|
9
|
+
const input = args.input ?? {};
|
|
10
|
+
switch (plan.operation) {
|
|
11
|
+
case 'list':
|
|
12
|
+
return executeList(adapter, plan, input, args);
|
|
13
|
+
case 'read':
|
|
14
|
+
return executeRead(adapter, plan, input, args);
|
|
15
|
+
case 'create':
|
|
16
|
+
return executeCreate(adapter, plan, input, args);
|
|
17
|
+
case 'update':
|
|
18
|
+
return executeUpdate(adapter, plan, input, args);
|
|
19
|
+
case 'delete':
|
|
20
|
+
return executeDelete(adapter, plan, input, args);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function resolveOperationPlan(dataSource, operation) {
|
|
24
|
+
const metadata = asRecord(operation.metadata);
|
|
25
|
+
const adapterId = resolveAdapterId(dataSource);
|
|
26
|
+
const collection = metadata?.collection;
|
|
27
|
+
const operationKind = metadata?.operation;
|
|
28
|
+
const schema = metadata?.schema;
|
|
29
|
+
if (adapterId === undefined) {
|
|
30
|
+
return invalidPlan(dataSource, operation, 'Database operation source does not reference an adapter.');
|
|
31
|
+
}
|
|
32
|
+
if (typeof collection !== 'string' || collection.trim().length === 0) {
|
|
33
|
+
return invalidPlan(dataSource, operation, 'Database operation metadata requires a collection.');
|
|
34
|
+
}
|
|
35
|
+
if (!isGeneratedCrudOperation(operationKind)) {
|
|
36
|
+
return invalidPlan(dataSource, operation, 'Database operation metadata requires a generated CRUD operation.');
|
|
37
|
+
}
|
|
38
|
+
if (schema !== undefined && schema !== null && typeof schema !== 'string') {
|
|
39
|
+
return invalidPlan(dataSource, operation, 'Database operation schema metadata must be a string or null.');
|
|
40
|
+
}
|
|
41
|
+
const metadataAdapterId = metadata?.adapterId;
|
|
42
|
+
if (metadataAdapterId !== undefined && metadataAdapterId !== adapterId) {
|
|
43
|
+
return invalidPlan(dataSource, operation, 'Database operation adapter metadata does not match its data source.');
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
ok: true,
|
|
47
|
+
adapterId,
|
|
48
|
+
collection,
|
|
49
|
+
schema: typeof schema === 'string' ? schema : undefined,
|
|
50
|
+
operation: operationKind,
|
|
51
|
+
primaryKey: resolvePrimaryKey(operation),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async function executeList(adapter, plan, input, args) {
|
|
55
|
+
const page = resolvePage(input);
|
|
56
|
+
if (!page.ok)
|
|
57
|
+
return failure(args, 'invalid-config', page.message);
|
|
58
|
+
const result = await adapter.select({
|
|
59
|
+
table: plan.collection,
|
|
60
|
+
schema: plan.schema,
|
|
61
|
+
page: page.value,
|
|
62
|
+
});
|
|
63
|
+
return resolveDbResult(args, result, (records) => records);
|
|
64
|
+
}
|
|
65
|
+
async function executeRead(adapter, plan, input, args) {
|
|
66
|
+
const identity = resolveIdentity(plan, input);
|
|
67
|
+
if (!identity.ok)
|
|
68
|
+
return failure(args, 'invalid-config', identity.message);
|
|
69
|
+
const result = await adapter.findById({
|
|
70
|
+
table: plan.collection,
|
|
71
|
+
schema: plan.schema,
|
|
72
|
+
id: identity.value,
|
|
73
|
+
idField: plan.primaryKey,
|
|
74
|
+
});
|
|
75
|
+
return resolveDbResult(args, result, (record) => record);
|
|
76
|
+
}
|
|
77
|
+
async function executeCreate(adapter, plan, input, args) {
|
|
78
|
+
const result = await adapter.insert({
|
|
79
|
+
table: plan.collection,
|
|
80
|
+
schema: plan.schema,
|
|
81
|
+
values: { ...input },
|
|
82
|
+
});
|
|
83
|
+
return resolveDbResult(args, result, (records) => records[0] ?? null);
|
|
84
|
+
}
|
|
85
|
+
async function executeUpdate(adapter, plan, input, args) {
|
|
86
|
+
const identity = resolveIdentity(plan, input);
|
|
87
|
+
if (!identity.ok)
|
|
88
|
+
return failure(args, 'invalid-config', identity.message);
|
|
89
|
+
const values = omitKey(input, plan.primaryKey);
|
|
90
|
+
if (Object.keys(values).length === 0) {
|
|
91
|
+
return failure(args, 'invalid-config', 'Generated update operation requires at least one value to update.');
|
|
92
|
+
}
|
|
93
|
+
const result = await adapter.update({
|
|
94
|
+
table: plan.collection,
|
|
95
|
+
schema: plan.schema,
|
|
96
|
+
values,
|
|
97
|
+
filters: [createIdentityFilter(plan.primaryKey, identity.value)],
|
|
98
|
+
});
|
|
99
|
+
return resolveDbResult(args, result, (records) => records[0] ?? null);
|
|
100
|
+
}
|
|
101
|
+
async function executeDelete(adapter, plan, input, args) {
|
|
102
|
+
const identity = resolveIdentity(plan, input);
|
|
103
|
+
if (!identity.ok)
|
|
104
|
+
return failure(args, 'invalid-config', identity.message);
|
|
105
|
+
const result = await adapter.delete({
|
|
106
|
+
table: plan.collection,
|
|
107
|
+
schema: plan.schema,
|
|
108
|
+
filters: [createIdentityFilter(plan.primaryKey, identity.value)],
|
|
109
|
+
});
|
|
110
|
+
return resolveDbResult(args, result, (records) => ({ deleted: records.length > 0 }));
|
|
111
|
+
}
|
|
112
|
+
function resolveDbResult(args, result, select) {
|
|
113
|
+
if (!result.ok)
|
|
114
|
+
return failure(args, 'database-operation-failed', result.error.message);
|
|
115
|
+
const value = toBindingValue(select(result.data));
|
|
116
|
+
if (value === undefined) {
|
|
117
|
+
return failure(args, 'invalid-config', 'Database adapter returned a non-serializable binding value.');
|
|
118
|
+
}
|
|
119
|
+
return { ok: true, data: value, diagnostics: [] };
|
|
120
|
+
}
|
|
121
|
+
function resolveAdapterId(dataSource) {
|
|
122
|
+
if (dataSource.kind === 'database')
|
|
123
|
+
return dataSource.adapter.id;
|
|
124
|
+
if (dataSource.origin === 'generated')
|
|
125
|
+
return dataSource.adapter.id;
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
function resolvePrimaryKey(operation) {
|
|
129
|
+
return operation.request?.parameters?.find((parameter) => parameter.location === 'path')?.name;
|
|
130
|
+
}
|
|
131
|
+
function resolveIdentity(plan, input) {
|
|
132
|
+
if (plan.primaryKey === undefined) {
|
|
133
|
+
return {
|
|
134
|
+
ok: false,
|
|
135
|
+
message: 'Generated read/update/delete operation requires primary-key metadata.',
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
const value = input[plan.primaryKey];
|
|
139
|
+
return typeof value === 'string' || (typeof value === 'number' && Number.isFinite(value))
|
|
140
|
+
? { ok: true, value }
|
|
141
|
+
: {
|
|
142
|
+
ok: false,
|
|
143
|
+
message: `Generated operation requires '${plan.primaryKey}' as a string or number.`,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function resolvePage(input) {
|
|
147
|
+
const { limit, offset } = input;
|
|
148
|
+
if (!isOptionalPageNumber(limit) || !isOptionalPageNumber(offset)) {
|
|
149
|
+
return {
|
|
150
|
+
ok: false,
|
|
151
|
+
message: 'Generated list operation limit/offset must be non-negative integers.',
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
if (limit === undefined && offset === undefined)
|
|
155
|
+
return { ok: true, value: undefined };
|
|
156
|
+
return { ok: true, value: { limit, offset } };
|
|
157
|
+
}
|
|
158
|
+
function isOptionalPageNumber(value) {
|
|
159
|
+
return (value === undefined || (typeof value === 'number' && Number.isInteger(value) && value >= 0));
|
|
160
|
+
}
|
|
161
|
+
function createIdentityFilter(field, value) {
|
|
162
|
+
return { field: field ?? 'id', operator: 'eq', value };
|
|
163
|
+
}
|
|
164
|
+
function omitKey(input, key) {
|
|
165
|
+
const values = {};
|
|
166
|
+
for (const [field, value] of Object.entries(input)) {
|
|
167
|
+
if (field !== key)
|
|
168
|
+
values[field] = value;
|
|
169
|
+
}
|
|
170
|
+
return values;
|
|
171
|
+
}
|
|
172
|
+
function isGeneratedCrudOperation(value) {
|
|
173
|
+
return (value === 'list' ||
|
|
174
|
+
value === 'read' ||
|
|
175
|
+
value === 'create' ||
|
|
176
|
+
value === 'update' ||
|
|
177
|
+
value === 'delete');
|
|
178
|
+
}
|
|
179
|
+
function invalidPlan(dataSource, operation, message) {
|
|
180
|
+
return {
|
|
181
|
+
ok: false,
|
|
182
|
+
result: failure({ dataSource, operation }, 'invalid-config', message),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function failure(args, code, message) {
|
|
186
|
+
const diagnostic = {
|
|
187
|
+
code,
|
|
188
|
+
dataSourceId: args.dataSource.id,
|
|
189
|
+
endpointId: args.operation.endpointId,
|
|
190
|
+
operationId: args.operation.id,
|
|
191
|
+
message,
|
|
192
|
+
severity: 'error',
|
|
193
|
+
};
|
|
194
|
+
return { ok: false, diagnostics: [diagnostic] };
|
|
195
|
+
}
|
|
196
|
+
function asRecord(value) {
|
|
197
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
198
|
+
? value
|
|
199
|
+
: undefined;
|
|
200
|
+
}
|
|
201
|
+
function toBindingValue(value) {
|
|
202
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean')
|
|
203
|
+
return value;
|
|
204
|
+
if (typeof value === 'number')
|
|
205
|
+
return Number.isFinite(value) ? value : undefined;
|
|
206
|
+
if (Array.isArray(value)) {
|
|
207
|
+
const items = [];
|
|
208
|
+
for (const item of value) {
|
|
209
|
+
const converted = toBindingValue(item);
|
|
210
|
+
if (converted === undefined)
|
|
211
|
+
return undefined;
|
|
212
|
+
items.push(converted);
|
|
213
|
+
}
|
|
214
|
+
return items;
|
|
215
|
+
}
|
|
216
|
+
const record = asRecord(value);
|
|
217
|
+
if (record === undefined)
|
|
218
|
+
return undefined;
|
|
219
|
+
const converted = {};
|
|
220
|
+
for (const [key, item] of Object.entries(record)) {
|
|
221
|
+
const bindingValue = toBindingValue(item);
|
|
222
|
+
if (bindingValue === undefined)
|
|
223
|
+
return undefined;
|
|
224
|
+
converted[key] = bindingValue;
|
|
225
|
+
}
|
|
226
|
+
return converted;
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=runtimeDatabaseOperationExecutor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeDatabaseOperationExecutor.js","sourceRoot":"","sources":["../src/runtimeDatabaseOperationExecutor.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n BindingValue,\n DataOperationConfig,\n DataSourceConfig,\n DataSourceDiagnostic,\n DbAdapter,\n DbFilter,\n DbRecord,\n} from '@ankhorage/contracts';\n\nimport type { RuntimeBindingOperationExecutionResult } from './runtimeBindings';\n\nexport async function executeRuntimeDatabaseOperation(args: {\n readonly dataSource: DataSourceConfig;\n readonly operation: DataOperationConfig;\n readonly input: Readonly<Record<string, BindingValue>> | undefined;\n readonly databaseAdapters: Readonly<Record<string, DbAdapter>> | undefined;\n}): Promise<RuntimeBindingOperationExecutionResult> {\n const plan = resolveOperationPlan(args.dataSource, args.operation);\n if (!plan.ok) return plan.result;\n\n const adapter = args.databaseAdapters?.[plan.adapterId];\n if (adapter === undefined) {\n return failure(\n args,\n 'missing-adapter',\n `Database adapter '${plan.adapterId}' is not available.`,\n );\n }\n\n const input = args.input ?? {};\n switch (plan.operation) {\n case 'list':\n return executeList(adapter, plan, input, args);\n case 'read':\n return executeRead(adapter, plan, input, args);\n case 'create':\n return executeCreate(adapter, plan, input, args);\n case 'update':\n return executeUpdate(adapter, plan, input, args);\n case 'delete':\n return executeDelete(adapter, plan, input, args);\n }\n}\n\ntype GeneratedCrudOperation = 'list' | 'read' | 'create' | 'update' | 'delete';\n\ninterface DatabaseOperationPlan {\n readonly adapterId: string;\n readonly collection: string;\n readonly schema?: string;\n readonly operation: GeneratedCrudOperation;\n readonly primaryKey?: string;\n}\n\ntype OperationPlanResult =\n | {\n readonly ok: true;\n readonly adapterId: string;\n readonly collection: string;\n readonly schema?: string;\n readonly operation: GeneratedCrudOperation;\n readonly primaryKey?: string;\n }\n | { readonly ok: false; readonly result: RuntimeBindingOperationExecutionResult };\n\nfunction resolveOperationPlan(\n dataSource: DataSourceConfig,\n operation: DataOperationConfig,\n): OperationPlanResult {\n const metadata = asRecord(operation.metadata);\n const adapterId = resolveAdapterId(dataSource);\n const collection = metadata?.collection;\n const operationKind = metadata?.operation;\n const schema = metadata?.schema;\n\n if (adapterId === undefined) {\n return invalidPlan(\n dataSource,\n operation,\n 'Database operation source does not reference an adapter.',\n );\n }\n if (typeof collection !== 'string' || collection.trim().length === 0) {\n return invalidPlan(dataSource, operation, 'Database operation metadata requires a collection.');\n }\n if (!isGeneratedCrudOperation(operationKind)) {\n return invalidPlan(\n dataSource,\n operation,\n 'Database operation metadata requires a generated CRUD operation.',\n );\n }\n if (schema !== undefined && schema !== null && typeof schema !== 'string') {\n return invalidPlan(\n dataSource,\n operation,\n 'Database operation schema metadata must be a string or null.',\n );\n }\n\n const metadataAdapterId = metadata?.adapterId;\n if (metadataAdapterId !== undefined && metadataAdapterId !== adapterId) {\n return invalidPlan(\n dataSource,\n operation,\n 'Database operation adapter metadata does not match its data source.',\n );\n }\n\n return {\n ok: true,\n adapterId,\n collection,\n schema: typeof schema === 'string' ? schema : undefined,\n operation: operationKind,\n primaryKey: resolvePrimaryKey(operation),\n };\n}\n\nasync function executeList(\n adapter: DbAdapter,\n plan: DatabaseOperationPlan,\n input: Readonly<Record<string, BindingValue>>,\n args: DatabaseExecutionArgs,\n): Promise<RuntimeBindingOperationExecutionResult> {\n const page = resolvePage(input);\n if (!page.ok) return failure(args, 'invalid-config', page.message);\n\n const result = await adapter.select({\n table: plan.collection,\n schema: plan.schema,\n page: page.value,\n });\n return resolveDbResult(args, result, (records) => records);\n}\n\nasync function executeRead(\n adapter: DbAdapter,\n plan: DatabaseOperationPlan,\n input: Readonly<Record<string, BindingValue>>,\n args: DatabaseExecutionArgs,\n): Promise<RuntimeBindingOperationExecutionResult> {\n const identity = resolveIdentity(plan, input);\n if (!identity.ok) return failure(args, 'invalid-config', identity.message);\n\n const result = await adapter.findById({\n table: plan.collection,\n schema: plan.schema,\n id: identity.value,\n idField: plan.primaryKey,\n });\n return resolveDbResult(args, result, (record) => record);\n}\n\nasync function executeCreate(\n adapter: DbAdapter,\n plan: DatabaseOperationPlan,\n input: Readonly<Record<string, BindingValue>>,\n args: DatabaseExecutionArgs,\n): Promise<RuntimeBindingOperationExecutionResult> {\n const result = await adapter.insert({\n table: plan.collection,\n schema: plan.schema,\n values: { ...input },\n });\n return resolveDbResult(args, result, (records) => records[0] ?? null);\n}\n\nasync function executeUpdate(\n adapter: DbAdapter,\n plan: DatabaseOperationPlan,\n input: Readonly<Record<string, BindingValue>>,\n args: DatabaseExecutionArgs,\n): Promise<RuntimeBindingOperationExecutionResult> {\n const identity = resolveIdentity(plan, input);\n if (!identity.ok) return failure(args, 'invalid-config', identity.message);\n\n const values = omitKey(input, plan.primaryKey);\n if (Object.keys(values).length === 0) {\n return failure(\n args,\n 'invalid-config',\n 'Generated update operation requires at least one value to update.',\n );\n }\n\n const result = await adapter.update({\n table: plan.collection,\n schema: plan.schema,\n values,\n filters: [createIdentityFilter(plan.primaryKey, identity.value)],\n });\n return resolveDbResult(args, result, (records) => records[0] ?? null);\n}\n\nasync function executeDelete(\n adapter: DbAdapter,\n plan: DatabaseOperationPlan,\n input: Readonly<Record<string, BindingValue>>,\n args: DatabaseExecutionArgs,\n): Promise<RuntimeBindingOperationExecutionResult> {\n const identity = resolveIdentity(plan, input);\n if (!identity.ok) return failure(args, 'invalid-config', identity.message);\n\n const result = await adapter.delete({\n table: plan.collection,\n schema: plan.schema,\n filters: [createIdentityFilter(plan.primaryKey, identity.value)],\n });\n return resolveDbResult(args, result, (records) => ({ deleted: records.length > 0 }));\n}\n\ntype DatabaseExecutionArgs = Pick<\n Parameters<typeof executeRuntimeDatabaseOperation>[0],\n 'dataSource' | 'operation'\n>;\n\nfunction resolveDbResult<TData>(\n args: DatabaseExecutionArgs,\n result:\n | { readonly ok: true; readonly data: TData }\n | { readonly ok: false; readonly error: { readonly message: string } },\n select: (data: TData) => unknown,\n): RuntimeBindingOperationExecutionResult {\n if (!result.ok) return failure(args, 'database-operation-failed', result.error.message);\n\n const value = toBindingValue(select(result.data));\n if (value === undefined) {\n return failure(\n args,\n 'invalid-config',\n 'Database adapter returned a non-serializable binding value.',\n );\n }\n return { ok: true, data: value, diagnostics: [] };\n}\n\nfunction resolveAdapterId(dataSource: DataSourceConfig): string | undefined {\n if (dataSource.kind === 'database') return dataSource.adapter.id;\n if (dataSource.origin === 'generated') return dataSource.adapter.id;\n return undefined;\n}\n\nfunction resolvePrimaryKey(operation: DataOperationConfig): string | undefined {\n return operation.request?.parameters?.find((parameter) => parameter.location === 'path')?.name;\n}\n\nfunction resolveIdentity(\n plan: DatabaseOperationPlan,\n input: Readonly<Record<string, BindingValue>>,\n):\n | { readonly ok: true; readonly value: string | number }\n | { readonly ok: false; readonly message: string } {\n if (plan.primaryKey === undefined) {\n return {\n ok: false,\n message: 'Generated read/update/delete operation requires primary-key metadata.',\n };\n }\n const value = input[plan.primaryKey];\n return typeof value === 'string' || (typeof value === 'number' && Number.isFinite(value))\n ? { ok: true, value }\n : {\n ok: false,\n message: `Generated operation requires '${plan.primaryKey}' as a string or number.`,\n };\n}\n\nfunction resolvePage(input: Readonly<Record<string, BindingValue>>):\n | {\n readonly ok: true;\n readonly value: { readonly limit?: number; readonly offset?: number } | undefined;\n }\n | { readonly ok: false; readonly message: string } {\n const { limit, offset } = input;\n if (!isOptionalPageNumber(limit) || !isOptionalPageNumber(offset)) {\n return {\n ok: false,\n message: 'Generated list operation limit/offset must be non-negative integers.',\n };\n }\n if (limit === undefined && offset === undefined) return { ok: true, value: undefined };\n return { ok: true, value: { limit, offset } };\n}\n\nfunction isOptionalPageNumber(value: BindingValue | undefined): value is number | undefined {\n return (\n value === undefined || (typeof value === 'number' && Number.isInteger(value) && value >= 0)\n );\n}\n\nfunction createIdentityFilter(field: string | undefined, value: string | number): DbFilter {\n return { field: field ?? 'id', operator: 'eq', value };\n}\n\nfunction omitKey(input: Readonly<Record<string, BindingValue>>, key: string | undefined): DbRecord {\n const values: DbRecord = {};\n for (const [field, value] of Object.entries(input)) {\n if (field !== key) values[field] = value;\n }\n return values;\n}\n\nfunction isGeneratedCrudOperation(value: unknown): value is GeneratedCrudOperation {\n return (\n value === 'list' ||\n value === 'read' ||\n value === 'create' ||\n value === 'update' ||\n value === 'delete'\n );\n}\n\nfunction invalidPlan(\n dataSource: DataSourceConfig,\n operation: DataOperationConfig,\n message: string,\n): OperationPlanResult {\n return {\n ok: false,\n result: failure({ dataSource, operation }, 'invalid-config', message),\n };\n}\n\nfunction failure(\n args: DatabaseExecutionArgs,\n code: string,\n message: string,\n): RuntimeBindingOperationExecutionResult {\n const diagnostic: DataSourceDiagnostic = {\n code,\n dataSourceId: args.dataSource.id,\n endpointId: args.operation.endpointId,\n operationId: args.operation.id,\n message,\n severity: 'error',\n };\n return { ok: false, diagnostics: [diagnostic] };\n}\n\nfunction asRecord(value: unknown): Readonly<Record<string, unknown>> | undefined {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Readonly<Record<string, unknown>>)\n : undefined;\n}\n\nfunction toBindingValue(value: unknown): BindingValue | undefined {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return value;\n if (typeof value === 'number') return Number.isFinite(value) ? value : undefined;\n if (Array.isArray(value)) {\n const items: BindingValue[] = [];\n for (const item of value) {\n const converted = toBindingValue(item);\n if (converted === undefined) return undefined;\n items.push(converted);\n }\n return items;\n }\n const record = asRecord(value);\n if (record === undefined) return undefined;\n const converted: Record<string, BindingValue> = {};\n for (const [key, item] of Object.entries(record)) {\n const bindingValue = toBindingValue(item);\n if (bindingValue === undefined) return undefined;\n converted[key] = bindingValue;\n }\n return converted;\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type MediaAsset, type MediaAssetRegistry } from '@ankhorage/contracts';
|
|
2
|
+
export type RuntimeResolvedMediaValue = string | number | Readonly<Record<string, unknown>>;
|
|
3
|
+
export interface RuntimeMediaAssetResolverArgs {
|
|
4
|
+
readonly asset: MediaAsset;
|
|
5
|
+
}
|
|
6
|
+
export type RuntimeMediaAssetResolver = (args: RuntimeMediaAssetResolverArgs) => Promise<RuntimeResolvedMediaValue | null> | RuntimeResolvedMediaValue | null;
|
|
7
|
+
export type RuntimeMediaResolutionCache = WeakMap<MediaAsset, WeakMap<RuntimeMediaAssetResolver, Promise<RuntimeResolvedMediaValue | null>>>;
|
|
8
|
+
export declare function createRuntimeMediaResolutionCache(): RuntimeMediaResolutionCache;
|
|
9
|
+
export declare function collectRuntimeMediaReferenceIds(value: unknown): readonly string[];
|
|
10
|
+
export declare function replaceRuntimeMediaReferences(value: unknown, resolvedById: ReadonlyMap<string, RuntimeResolvedMediaValue>): unknown;
|
|
11
|
+
export declare function resolveRuntimeMediaAsset(asset: MediaAsset, resolver: RuntimeMediaAssetResolver | undefined, cache: RuntimeMediaResolutionCache): Promise<RuntimeResolvedMediaValue | null>;
|
|
12
|
+
export declare function createSyncRuntimeMediaResolutionMap(ids: readonly string[], mediaAssets: MediaAssetRegistry | undefined): Map<string, RuntimeResolvedMediaValue>;
|
|
13
|
+
//# sourceMappingURL=runtimeMedia.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeMedia.d.ts","sourceRoot":"","sources":["../src/runtimeMedia.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,kBAAkB,EACxB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,MAAM,yBAAyB,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE5F,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,MAAM,MAAM,yBAAyB,GAAG,CACtC,IAAI,EAAE,6BAA6B,KAChC,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,GAAG,yBAAyB,GAAG,IAAI,CAAC;AAElF,MAAM,MAAM,2BAA2B,GAAG,OAAO,CAC/C,UAAU,EACV,OAAO,CAAC,yBAAyB,EAAE,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAAC,CAC9E,CAAC;AAIF,wBAAgB,iCAAiC,IAAI,2BAA2B,CAE/E;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAIjF;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,OAAO,EACd,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,yBAAyB,CAAC,GAC3D,OAAO,CAGT;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,yBAAyB,GAAG,SAAS,EAC/C,KAAK,EAAE,2BAA2B,GACjC,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAgB3C;AAED,wBAAgB,mCAAmC,CACjD,GAAG,EAAE,SAAS,MAAM,EAAE,EACtB,WAAW,EAAE,kBAAkB,GAAG,SAAS,GAC1C,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,CASxC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { isMediaAssetReference, } from '@ankhorage/contracts';
|
|
2
|
+
const OMIT_MEDIA_VALUE = Symbol('omit-runtime-media-value');
|
|
3
|
+
export function createRuntimeMediaResolutionCache() {
|
|
4
|
+
return new WeakMap();
|
|
5
|
+
}
|
|
6
|
+
export function collectRuntimeMediaReferenceIds(value) {
|
|
7
|
+
const ids = new Set();
|
|
8
|
+
collectMediaReferenceIds(value, ids);
|
|
9
|
+
return [...ids].sort();
|
|
10
|
+
}
|
|
11
|
+
export function replaceRuntimeMediaReferences(value, resolvedById) {
|
|
12
|
+
const replaced = replaceMediaValue(value, resolvedById);
|
|
13
|
+
return replaced === OMIT_MEDIA_VALUE ? undefined : replaced;
|
|
14
|
+
}
|
|
15
|
+
export function resolveRuntimeMediaAsset(asset, resolver, cache) {
|
|
16
|
+
if (asset.source.kind === 'url')
|
|
17
|
+
return Promise.resolve(asset.source.url);
|
|
18
|
+
if (!resolver)
|
|
19
|
+
return Promise.resolve(null);
|
|
20
|
+
let resolverCache = cache.get(asset);
|
|
21
|
+
if (!resolverCache) {
|
|
22
|
+
resolverCache = new WeakMap();
|
|
23
|
+
cache.set(asset, resolverCache);
|
|
24
|
+
}
|
|
25
|
+
const cached = resolverCache.get(resolver);
|
|
26
|
+
if (cached)
|
|
27
|
+
return cached;
|
|
28
|
+
const pending = Promise.resolve(resolver({ asset })).catch(() => null);
|
|
29
|
+
resolverCache.set(resolver, pending);
|
|
30
|
+
return pending;
|
|
31
|
+
}
|
|
32
|
+
export function createSyncRuntimeMediaResolutionMap(ids, mediaAssets) {
|
|
33
|
+
const resolved = new Map();
|
|
34
|
+
for (const id of ids) {
|
|
35
|
+
const asset = mediaAssets?.[id];
|
|
36
|
+
if (asset?.source.kind === 'url')
|
|
37
|
+
resolved.set(id, asset.source.url);
|
|
38
|
+
}
|
|
39
|
+
return resolved;
|
|
40
|
+
}
|
|
41
|
+
function collectMediaReferenceIds(value, ids) {
|
|
42
|
+
if (isMediaAssetReference(value)) {
|
|
43
|
+
ids.add(value.mediaId.trim());
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (Array.isArray(value)) {
|
|
47
|
+
value.forEach((item) => collectMediaReferenceIds(item, ids));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (!isPlainObject(value))
|
|
51
|
+
return;
|
|
52
|
+
Object.values(value).forEach((item) => collectMediaReferenceIds(item, ids));
|
|
53
|
+
}
|
|
54
|
+
function replaceMediaValue(value, resolvedById) {
|
|
55
|
+
if (isMediaAssetReference(value)) {
|
|
56
|
+
return resolvedById.get(value.mediaId.trim()) ?? OMIT_MEDIA_VALUE;
|
|
57
|
+
}
|
|
58
|
+
if (Array.isArray(value)) {
|
|
59
|
+
return value.map((item) => {
|
|
60
|
+
const replaced = replaceMediaValue(item, resolvedById);
|
|
61
|
+
return replaced === OMIT_MEDIA_VALUE ? undefined : replaced;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
if (!isPlainObject(value))
|
|
65
|
+
return value;
|
|
66
|
+
const result = {};
|
|
67
|
+
for (const [key, item] of Object.entries(value)) {
|
|
68
|
+
const replaced = replaceMediaValue(item, resolvedById);
|
|
69
|
+
if (replaced !== OMIT_MEDIA_VALUE)
|
|
70
|
+
result[key] = replaced;
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
function isPlainObject(value) {
|
|
75
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
76
|
+
return false;
|
|
77
|
+
const prototype = Reflect.getPrototypeOf(value);
|
|
78
|
+
return prototype === Object.prototype || prototype === null;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=runtimeMedia.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeMedia.js","sourceRoot":"","sources":["../src/runtimeMedia.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isMediaAssetReference,\n type MediaAsset,\n type MediaAssetRegistry,\n} from '@ankhorage/contracts';\n\nexport type RuntimeResolvedMediaValue = string | number | Readonly<Record<string, unknown>>;\n\nexport interface RuntimeMediaAssetResolverArgs {\n readonly asset: MediaAsset;\n}\n\nexport type RuntimeMediaAssetResolver = (\n args: RuntimeMediaAssetResolverArgs,\n) => Promise<RuntimeResolvedMediaValue | null> | RuntimeResolvedMediaValue | null;\n\nexport type RuntimeMediaResolutionCache = WeakMap<\n MediaAsset,\n WeakMap<RuntimeMediaAssetResolver, Promise<RuntimeResolvedMediaValue | null>>\n>;\n\nconst OMIT_MEDIA_VALUE = Symbol('omit-runtime-media-value');\n\nexport function createRuntimeMediaResolutionCache(): RuntimeMediaResolutionCache {\n return new WeakMap();\n}\n\nexport function collectRuntimeMediaReferenceIds(value: unknown): readonly string[] {\n const ids = new Set<string>();\n collectMediaReferenceIds(value, ids);\n return [...ids].sort();\n}\n\nexport function replaceRuntimeMediaReferences(\n value: unknown,\n resolvedById: ReadonlyMap<string, RuntimeResolvedMediaValue>,\n): unknown {\n const replaced = replaceMediaValue(value, resolvedById);\n return replaced === OMIT_MEDIA_VALUE ? undefined : replaced;\n}\n\nexport function resolveRuntimeMediaAsset(\n asset: MediaAsset,\n resolver: RuntimeMediaAssetResolver | undefined,\n cache: RuntimeMediaResolutionCache,\n): Promise<RuntimeResolvedMediaValue | null> {\n if (asset.source.kind === 'url') return Promise.resolve(asset.source.url);\n if (!resolver) return Promise.resolve(null);\n\n let resolverCache = cache.get(asset);\n if (!resolverCache) {\n resolverCache = new WeakMap();\n cache.set(asset, resolverCache);\n }\n\n const cached = resolverCache.get(resolver);\n if (cached) return cached;\n\n const pending = Promise.resolve(resolver({ asset })).catch(() => null);\n resolverCache.set(resolver, pending);\n return pending;\n}\n\nexport function createSyncRuntimeMediaResolutionMap(\n ids: readonly string[],\n mediaAssets: MediaAssetRegistry | undefined,\n): Map<string, RuntimeResolvedMediaValue> {\n const resolved = new Map<string, RuntimeResolvedMediaValue>();\n\n for (const id of ids) {\n const asset = mediaAssets?.[id];\n if (asset?.source.kind === 'url') resolved.set(id, asset.source.url);\n }\n\n return resolved;\n}\n\nfunction collectMediaReferenceIds(value: unknown, ids: Set<string>): void {\n if (isMediaAssetReference(value)) {\n ids.add(value.mediaId.trim());\n return;\n }\n\n if (Array.isArray(value)) {\n value.forEach((item) => collectMediaReferenceIds(item, ids));\n return;\n }\n\n if (!isPlainObject(value)) return;\n Object.values(value).forEach((item) => collectMediaReferenceIds(item, ids));\n}\n\nfunction replaceMediaValue(\n value: unknown,\n resolvedById: ReadonlyMap<string, RuntimeResolvedMediaValue>,\n): unknown {\n if (isMediaAssetReference(value)) {\n return resolvedById.get(value.mediaId.trim()) ?? OMIT_MEDIA_VALUE;\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => {\n const replaced = replaceMediaValue(item, resolvedById);\n return replaced === OMIT_MEDIA_VALUE ? undefined : replaced;\n });\n }\n\n if (!isPlainObject(value)) return value;\n\n const result: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) {\n const replaced = replaceMediaValue(item, resolvedById);\n if (replaced !== OMIT_MEDIA_VALUE) result[key] = replaced;\n }\n return result;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const prototype = Reflect.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type RuntimeMediaResolutionCache } from './runtimeMedia';
|
|
3
|
+
export declare function useRuntimeMediaResolutionCache(): RuntimeMediaResolutionCache;
|
|
4
|
+
export declare function RuntimeMediaResolutionCacheProvider(props: {
|
|
5
|
+
readonly value: RuntimeMediaResolutionCache;
|
|
6
|
+
readonly children: React.ReactNode;
|
|
7
|
+
}): React.JSX.Element;
|
|
8
|
+
//# sourceMappingURL=runtimeMediaCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeMediaCache.d.ts","sourceRoot":"","sources":["../src/runtimeMediaCache.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAC;AAElE,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,gBAAgB,CAAC;AAIxB,wBAAgB,8BAA8B,IAAI,2BAA2B,CAI5E;AAED,wBAAgB,mCAAmC,CAAC,KAAK,EAAE;IACzD,QAAQ,CAAC,KAAK,EAAE,2BAA2B,CAAC;IAC5C,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CACpC,qBAMA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React, { createContext, useContext, useMemo } from 'react';
|
|
2
|
+
import { createRuntimeMediaResolutionCache, } from './runtimeMedia';
|
|
3
|
+
const RuntimeMediaCacheContext = createContext(null);
|
|
4
|
+
export function useRuntimeMediaResolutionCache() {
|
|
5
|
+
const inherited = useContext(RuntimeMediaCacheContext);
|
|
6
|
+
const local = useMemo(() => createRuntimeMediaResolutionCache(), []);
|
|
7
|
+
return inherited ?? local;
|
|
8
|
+
}
|
|
9
|
+
export function RuntimeMediaResolutionCacheProvider(props) {
|
|
10
|
+
return (<RuntimeMediaCacheContext.Provider value={props.value}>
|
|
11
|
+
{props.children}
|
|
12
|
+
</RuntimeMediaCacheContext.Provider>);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=runtimeMediaCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeMediaCache.js","sourceRoot":"","sources":["../src/runtimeMediaCache.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAElE,OAAO,EACL,iCAAiC,GAElC,MAAM,gBAAgB,CAAC;AAExB,MAAM,wBAAwB,GAAG,aAAa,CAAqC,IAAI,CAAC,CAAC;AAEzF,MAAM,UAAU,8BAA8B;IAC5C,MAAM,SAAS,GAAG,UAAU,CAAC,wBAAwB,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,iCAAiC,EAAE,EAAE,EAAE,CAAC,CAAC;IACrE,OAAO,SAAS,IAAI,KAAK,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,mCAAmC,CAAC,KAGnD;IACC,OAAO,CACL,CAAC,wBAAwB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CACpD;MAAA,CAAC,KAAK,CAAC,QAAQ,CACjB;IAAA,EAAE,wBAAwB,CAAC,QAAQ,CAAC,CACrC,CAAC;AACJ,CAAC","sourcesContent":["import React, { createContext, useContext, useMemo } from 'react';\n\nimport {\n createRuntimeMediaResolutionCache,\n type RuntimeMediaResolutionCache,\n} from './runtimeMedia';\n\nconst RuntimeMediaCacheContext = createContext<RuntimeMediaResolutionCache | null>(null);\n\nexport function useRuntimeMediaResolutionCache(): RuntimeMediaResolutionCache {\n const inherited = useContext(RuntimeMediaCacheContext);\n const local = useMemo(() => createRuntimeMediaResolutionCache(), []);\n return inherited ?? local;\n}\n\nexport function RuntimeMediaResolutionCacheProvider(props: {\n readonly value: RuntimeMediaResolutionCache;\n readonly children: React.ReactNode;\n}) {\n return (\n <RuntimeMediaCacheContext.Provider value={props.value}>\n {props.children}\n </RuntimeMediaCacheContext.Provider>\n );\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DataSourceDiagnostic, OperationScreenDataLoaderDefinition, ScreenSpec } from '@ankhorage/contracts';
|
|
2
2
|
import { type RuntimeBindingOperationExecutor, type RuntimeBindingOperationResultCache, type RuntimeBindingResolutionContext } from './runtimeBindings';
|
|
3
3
|
export interface RuntimeScreenOperationLoaderState {
|
|
4
4
|
readonly dependencyKey: string;
|
|
@@ -15,7 +15,6 @@ export interface RuntimeScreenOperationLoaderLifecycle {
|
|
|
15
15
|
readonly activeRequestId: number;
|
|
16
16
|
readonly activeRequestKey: string | null;
|
|
17
17
|
}
|
|
18
|
-
export declare function resolveScreenApiLoaders(screen: ScreenSpec): readonly ApiScreenDataLoaderDefinition[];
|
|
19
18
|
export declare function resolveScreenOperationLoaders(screen: ScreenSpec): readonly OperationScreenDataLoaderDefinition[];
|
|
20
19
|
export declare function createRuntimeScreenLoaderRequestKey(args: {
|
|
21
20
|
readonly screenId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimeScreenLoaders.d.ts","sourceRoot":"","sources":["../src/runtimeScreenLoaders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"runtimeScreenLoaders.d.ts","sourceRoot":"","sources":["../src/runtimeScreenLoaders.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,11 +2,8 @@ import React from 'react';
|
|
|
2
2
|
import { createRuntimeBindingOperationKey, resolveBindingInputMapSync, resolveRuntimeBindingOperationSelection, } from './runtimeBindings';
|
|
3
3
|
const EMPTY_RUNTIME_SCREEN_OPERATION_LOADER_DIAGNOSTICS = Object.freeze([]);
|
|
4
4
|
const EMPTY_RUNTIME_SCREEN_OPERATION_RESULTS = Object.freeze({});
|
|
5
|
-
export function resolveScreenApiLoaders(screen) {
|
|
6
|
-
return (screen.dataLoaders ?? []).filter((loader) => loader.kind === 'api');
|
|
7
|
-
}
|
|
8
5
|
export function resolveScreenOperationLoaders(screen) {
|
|
9
|
-
return
|
|
6
|
+
return screen.dataLoaders ?? [];
|
|
10
7
|
}
|
|
11
8
|
export function createRuntimeScreenLoaderRequestKey(args) {
|
|
12
9
|
return createRuntimeScreenOperationLoaderPlan({
|