@loutrejs/loutre 0.5.0 → 0.7.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.
Files changed (188) hide show
  1. package/README.md +63 -32
  2. package/dist/adapters/aws-lambda.d.ts +5 -3
  3. package/dist/adapters/aws-lambda.js +53 -23
  4. package/dist/adapters/bun.d.ts +7 -4
  5. package/dist/adapters/bun.js +52 -42
  6. package/dist/adapters/cloudflare-workers.d.ts +5 -3
  7. package/dist/adapters/cloudflare-workers.js +23 -28
  8. package/dist/adapters/deno.d.ts +7 -4
  9. package/dist/adapters/deno.js +94 -57
  10. package/dist/adapters/electron.d.ts +13 -5
  11. package/dist/adapters/electron.js +76 -28
  12. package/dist/application/definition.d.ts +31 -0
  13. package/dist/application/definition.js +16 -0
  14. package/dist/application/index.d.ts +4 -63
  15. package/dist/application/index.js +2 -11
  16. package/dist/application/kernel-internal.d.ts +2 -0
  17. package/dist/application/kernel-internal.js +10 -0
  18. package/dist/application/kernel.d.ts +22 -0
  19. package/dist/application/kernel.js +65 -0
  20. package/dist/core/diagnostic.d.ts +9 -0
  21. package/dist/core/diagnostic.js +9 -0
  22. package/dist/core/extension.d.ts +118 -0
  23. package/dist/core/extension.js +73 -0
  24. package/dist/core/generic-layer.d.ts +26 -0
  25. package/dist/core/generic-layer.js +116 -0
  26. package/dist/core/index.d.ts +32 -15
  27. package/dist/core/index.js +15 -15
  28. package/dist/core/injection.d.ts +4 -13
  29. package/dist/core/injection.js +63 -0
  30. package/dist/core/instrumentation.d.ts +36 -0
  31. package/dist/core/model/context.d.ts +18 -0
  32. package/dist/core/model/context.js +34 -0
  33. package/dist/core/model/lifecycle.d.ts +5 -0
  34. package/dist/core/model/lifecycle.js +44 -0
  35. package/dist/core/model/modules.d.ts +2 -0
  36. package/dist/core/model/modules.js +101 -0
  37. package/dist/core/model/providers.d.ts +4 -0
  38. package/dist/core/model/providers.js +74 -0
  39. package/dist/core/model/snapshot.d.ts +6 -0
  40. package/dist/core/model/snapshot.js +31 -0
  41. package/dist/core/model/types.d.ts +78 -0
  42. package/dist/core/model/types.js +1 -0
  43. package/dist/core/model/validation.d.ts +4 -0
  44. package/dist/core/model/validation.js +40 -0
  45. package/dist/core/model/visibility.d.ts +4 -0
  46. package/dist/core/model/visibility.js +20 -0
  47. package/dist/core/model.d.ts +10 -0
  48. package/dist/core/model.js +346 -0
  49. package/dist/core/module.d.ts +8 -13
  50. package/dist/core/source-location.d.ts +8 -0
  51. package/dist/core/source-location.js +31 -0
  52. package/dist/core/token-internal.d.ts +3 -0
  53. package/dist/core/token-internal.js +4 -0
  54. package/dist/core/type.d.ts +7 -0
  55. package/dist/core/type.js +4 -0
  56. package/dist/devtools/capsule.d.ts +51 -0
  57. package/dist/devtools/capsule.js +245 -0
  58. package/dist/devtools/index.d.ts +11 -0
  59. package/dist/devtools/index.js +6 -0
  60. package/dist/devtools/inspector.d.ts +57 -0
  61. package/dist/devtools/inspector.js +1 -0
  62. package/dist/devtools/module.d.ts +18 -0
  63. package/dist/devtools/module.js +26 -0
  64. package/dist/devtools/observer.d.ts +77 -0
  65. package/dist/devtools/observer.js +10 -0
  66. package/dist/devtools/protocol.d.ts +1 -0
  67. package/dist/devtools/protocol.js +1 -0
  68. package/dist/devtools/provider-instrumentation.d.ts +14 -0
  69. package/dist/devtools/provider-instrumentation.js +117 -0
  70. package/dist/devtools/runtime.d.ts +20 -0
  71. package/dist/devtools/runtime.js +519 -0
  72. package/dist/devtools/values.d.ts +35 -0
  73. package/dist/devtools/values.js +175 -0
  74. package/dist/generated/version.d.ts +1 -1
  75. package/dist/generated/version.js +1 -1
  76. package/dist/graph/index.d.ts +2 -3
  77. package/dist/graph/index.js +1 -3
  78. package/dist/graph/model.d.ts +34 -0
  79. package/dist/graph/model.js +127 -0
  80. package/dist/http/auth.d.ts +46 -0
  81. package/dist/http/auth.js +96 -0
  82. package/dist/http/client.d.ts +28 -31
  83. package/dist/http/client.js +58 -44
  84. package/dist/http/cors-internal.d.ts +29 -0
  85. package/dist/http/cors-internal.js +160 -0
  86. package/dist/http/cors.d.ts +5 -8
  87. package/dist/http/cors.js +7 -165
  88. package/dist/http/extension.d.ts +348 -0
  89. package/dist/http/extension.js +1061 -0
  90. package/dist/http/index.d.ts +9 -7
  91. package/dist/http/index.js +5 -7
  92. package/dist/{application → http}/openapi.d.ts +12 -3
  93. package/dist/{application → http}/openapi.js +164 -102
  94. package/dist/http/path.d.ts +1 -42
  95. package/dist/http/path.js +1 -2
  96. package/dist/http/runtime/request.d.ts +17 -0
  97. package/dist/http/runtime/request.js +109 -0
  98. package/dist/http/runtime/response.d.ts +18 -0
  99. package/dist/http/runtime/response.js +108 -0
  100. package/dist/index.d.ts +4 -0
  101. package/dist/index.js +2 -0
  102. package/dist/message-port/extension.d.ts +66 -0
  103. package/dist/message-port/extension.js +411 -0
  104. package/dist/message-port/index.d.ts +4 -73
  105. package/dist/message-port/index.js +2 -189
  106. package/dist/message-port/transport.d.ts +11 -0
  107. package/dist/message-port/transport.js +45 -0
  108. package/dist/runtime/async-iterator-lifecycle.d.ts +12 -0
  109. package/dist/runtime/async-iterator-lifecycle.js +95 -0
  110. package/dist/runtime/capability.d.ts +11 -11
  111. package/dist/runtime/capability.js +3 -3
  112. package/dist/runtime/di.d.ts +5 -21
  113. package/dist/runtime/di.js +22 -289
  114. package/dist/runtime/execution-tracker.d.ts +8 -0
  115. package/dist/runtime/execution-tracker.js +54 -0
  116. package/dist/runtime/index.d.ts +15 -9
  117. package/dist/runtime/index.js +9 -9
  118. package/dist/runtime/ingress-gate.d.ts +7 -0
  119. package/dist/runtime/ingress-gate.js +33 -0
  120. package/dist/runtime/kernel.d.ts +25 -0
  121. package/dist/runtime/kernel.js +447 -0
  122. package/dist/runtime/logger.d.ts +2 -0
  123. package/dist/runtime/logger.js +2 -0
  124. package/dist/runtime/node-capabilities.d.ts +1 -1
  125. package/dist/runtime/node-capabilities.js +1 -1
  126. package/dist/runtime/server-port.d.ts +2 -0
  127. package/dist/runtime/server-port.js +11 -0
  128. package/dist/tasks/extension.d.ts +144 -0
  129. package/dist/tasks/extension.js +525 -0
  130. package/dist/tasks/index.d.ts +2 -0
  131. package/dist/tasks/index.js +1 -0
  132. package/dist/tasks/runtime/cron.d.ts +6 -0
  133. package/dist/tasks/runtime/cron.js +89 -0
  134. package/dist/websocket/errors.d.ts +9 -0
  135. package/dist/websocket/errors.js +18 -0
  136. package/dist/websocket/extension.d.ts +154 -0
  137. package/dist/websocket/extension.js +533 -0
  138. package/dist/websocket/index.d.ts +3 -0
  139. package/dist/websocket/index.js +2 -0
  140. package/package.json +16 -16
  141. package/dist/application/binding.d.ts +0 -33
  142. package/dist/application/binding.js +0 -295
  143. package/dist/application/host.d.ts +0 -8
  144. package/dist/application/host.js +0 -14
  145. package/dist/application/queue.d.ts +0 -3
  146. package/dist/application/queue.js +0 -4
  147. package/dist/application/scheduler.d.ts +0 -2
  148. package/dist/application/scheduler.js +0 -45
  149. package/dist/core/context-key.d.ts +0 -16
  150. package/dist/core/context-key.js +0 -17
  151. package/dist/core/contract-internal.d.ts +0 -22
  152. package/dist/core/contract-internal.js +0 -61
  153. package/dist/core/contract.d.ts +0 -96
  154. package/dist/core/contract.js +0 -88
  155. package/dist/core/execution.d.ts +0 -78
  156. package/dist/core/execution.js +0 -61
  157. package/dist/core/implementation.d.ts +0 -44
  158. package/dist/core/implementation.js +0 -35
  159. package/dist/core/layer.d.ts +0 -137
  160. package/dist/core/layer.js +0 -81
  161. package/dist/graph/compiler.d.ts +0 -4
  162. package/dist/graph/compiler.js +0 -228
  163. package/dist/graph/graph.d.ts +0 -18
  164. package/dist/graph/graph.js +0 -1118
  165. package/dist/graph/ir.d.ts +0 -175
  166. package/dist/http/application.d.ts +0 -18
  167. package/dist/http/application.js +0 -515
  168. package/dist/http/basic-auth.d.ts +0 -37
  169. package/dist/http/basic-auth.js +0 -67
  170. package/dist/http/definitions.d.ts +0 -363
  171. package/dist/http/definitions.js +0 -310
  172. package/dist/http/hosted-protocol.d.ts +0 -4
  173. package/dist/http/hosted-protocol.js +0 -4
  174. package/dist/http/internal.d.ts +0 -8
  175. package/dist/http/internal.js +0 -1
  176. package/dist/http/params.d.ts +0 -2
  177. package/dist/http/params.js +0 -19
  178. package/dist/http/request-body.d.ts +0 -4
  179. package/dist/http/request-body.js +0 -6
  180. package/dist/http/validate.d.ts +0 -20
  181. package/dist/http/validate.js +0 -6
  182. package/dist/message-port/environment.d.ts +0 -2
  183. package/dist/message-port/environment.js +0 -4
  184. package/dist/runtime/application.d.ts +0 -38
  185. package/dist/runtime/application.js +0 -339
  186. package/dist/runtime/pipeline.d.ts +0 -11
  187. package/dist/runtime/pipeline.js +0 -161
  188. /package/dist/{graph/ir.js → core/instrumentation.js} +0 -0
@@ -1,96 +0,0 @@
1
- import { contractNodeBinding, contractNodeKindType, protocolNamespaceType } from './contract-internal.js';
2
- export interface ProtocolDescriptor<TName extends string = string, TContext = unknown, TResult = unknown, TDispatchKey extends string | null = string | null, TCapabilities extends readonly string[] = readonly string[]> {
3
- readonly kind: 'protocol';
4
- readonly protocol: TName;
5
- readonly interaction?: InteractionMode;
6
- readonly dispatchKey: TDispatchKey;
7
- readonly capabilities?: TCapabilities;
8
- readonly '~context'?: TContext;
9
- readonly '~result'?: TResult;
10
- }
11
- export type InteractionMode = 'unary' | 'server-stream' | 'client-stream' | 'duplex';
12
- export interface ProcedureDefinition<TProtocols extends Record<string, ProtocolDescriptor> = Record<string, ProtocolDescriptor>> {
13
- readonly kind: 'procedure';
14
- readonly protocols: TProtocols;
15
- }
16
- export interface ProtocolGroup<TName extends string = string, TProcedures extends Record<string, ProtocolDescriptor<TName>> = Record<string, ProtocolDescriptor<TName>>> {
17
- readonly kind: 'protocol-group';
18
- readonly protocol: TName;
19
- readonly procedures: TProcedures;
20
- }
21
- export declare function protocolGroup<const TName extends string, const TProcedures extends Record<string, ProtocolDescriptor<TName>>>(protocol: TName, procedures: TProcedures): ProtocolGroup<TName, TProcedures>;
22
- export interface ContractDefinition<TProcedures extends Record<string, ProcedureDefinition> = Record<string, ProcedureDefinition>> {
23
- readonly kind: 'contract';
24
- readonly procedures: TProcedures;
25
- }
26
- export interface ResolvedContractNode<TContract extends ContractDefinition = ContractDefinition, TKind extends 'leaf' | 'branch' = 'leaf' | 'branch'> {
27
- readonly [contractNodeBinding]: TContract;
28
- readonly [contractNodeKindType]: TKind;
29
- }
30
- export type ContractBinding = ContractDefinition | ResolvedContractNode;
31
- export type ContractOfBinding<TBinding extends ContractBinding> = TBinding extends ResolvedContractNode<infer TContract> ? TContract : TBinding extends ContractDefinition ? TBinding : never;
32
- type ProcedureNamesOfGroup<TGroup> = TGroup extends ProtocolGroup<string, infer TProcedures> ? keyof TProcedures & string : never;
33
- type ProcedureNamesOfGroups<TGroups extends readonly ProtocolGroup[]> = ProcedureNamesOfGroup<TGroups[number]>;
34
- type ProtocolOfGroupProcedure<TGroup, TProcedure extends string> = TGroup extends ProtocolGroup<infer TProtocol, infer TProcedures> ? TProcedure extends keyof TProcedures ? {
35
- readonly [K in TProtocol]: TProcedures[TProcedure];
36
- } : never : never;
37
- type ProceduresFromGroups<TGroups extends readonly ProtocolGroup[]> = {
38
- [TProcedure in ProcedureNamesOfGroups<TGroups>]: ProcedureDefinition<UnionToIntersection<ProtocolOfGroupProcedure<TGroups[number], TProcedure>> extends infer TProtocols extends Record<string, ProtocolDescriptor> ? TProtocols : never>;
39
- };
40
- type ProcedureProtocolKeysOfGroup<TGroup> = TGroup extends ProtocolGroup<infer TProtocol, infer TProcedures> ? `${keyof TProcedures & string}.${TProtocol}` : never;
41
- type DuplicateGroupProcedureProtocolKeys<TGroups extends readonly ProtocolGroup[], TSeen extends string = never> = number extends TGroups['length'] ? never : TGroups extends readonly [
42
- infer THead extends ProtocolGroup,
43
- ...infer TTail extends readonly ProtocolGroup[]
44
- ] ? Extract<ProcedureProtocolKeysOfGroup<THead>, TSeen> | DuplicateGroupProcedureProtocolKeys<TTail, TSeen | ProcedureProtocolKeysOfGroup<THead>> : never;
45
- type ProtocolNamespaceOfGroup<TGroup> = TGroup extends {
46
- readonly protocol: infer TProtocol extends string;
47
- readonly procedures: infer TProcedures;
48
- } ? TProcedures extends object ? TProcedures[keyof TProcedures] extends {
49
- readonly [protocolNamespaceType]: infer TNamespace;
50
- } ? [TNamespace] extends [never] ? never : {
51
- readonly [K in TProtocol]: TNamespace;
52
- } : never : never : never;
53
- type ProtocolNamespaceNodeKeysOfGroup<TGroup> = ProtocolNamespaceOfGroup<TGroup> extends infer TNamespaces ? TNamespaces extends Readonly<Record<string, unknown>> ? {
54
- [TProtocol in keyof TNamespaces & string]: TNamespaces[TProtocol] extends object ? `${TProtocol}.${keyof TNamespaces[TProtocol] & string}` : never;
55
- }[keyof TNamespaces & string] : never : never;
56
- type DuplicateGroupProtocolNamespaceNodeKeys<TGroups extends readonly ProtocolGroup[], TSeen extends string = never> = number extends TGroups['length'] ? never : TGroups extends readonly [
57
- infer THead extends ProtocolGroup,
58
- ...infer TTail extends readonly ProtocolGroup[]
59
- ] ? Extract<ProtocolNamespaceNodeKeysOfGroup<THead>, TSeen> | DuplicateGroupProtocolNamespaceNodeKeys<TTail, TSeen | ProtocolNamespaceNodeKeysOfGroup<THead>> : never;
60
- type ProtocolNamespacesOfGroups<TGroups extends readonly ProtocolGroup[]> = [
61
- ProtocolNamespaceOfGroup<TGroups[number]>
62
- ] extends [never] ? unknown : UnionToIntersection<ProtocolNamespaceOfGroup<TGroups[number]>>;
63
- type ContractFromGroups<TGroups extends readonly ProtocolGroup[]> = ContractDefinition<ProceduresFromGroups<TGroups>> & ProtocolNamespacesOfGroups<TGroups>;
64
- type ContractGroupsOf<TGroups extends readonly unknown[]> = TGroups extends readonly ProtocolGroup[] ? TGroups : never;
65
- type ContractArgumentValidation<TGroups extends readonly unknown[]> = TGroups extends readonly [] ? readonly [error: 'contract requires at least one protocol group'] : TGroups extends readonly ProtocolGroup[] ? [DuplicateGroupProcedureProtocolKeys<TGroups>] extends [never] ? [DuplicateGroupProtocolNamespaceNodeKeys<TGroups>] extends [never] ? [
66
- DuplicateDispatchKeys<ProtocolDispatchEntries<ProceduresFromGroups<TGroups>>>
67
- ] extends [never] ? readonly [] : readonly [error: 'contract contains duplicate dispatch keys'] : readonly [
68
- error: 'contract contains duplicate protocol namespace nodes'
69
- ] : readonly [error: 'contract contains duplicate procedure protocols'] : readonly [error: 'contract entries must be protocol groups'];
70
- declare function defineContract<const TGroups extends readonly unknown[]>(groups: TGroups, ...validation: ContractArgumentValidation<TGroups>): ContractFromGroups<ContractGroupsOf<TGroups>>;
71
- type UnionToIntersection<T> = (T extends unknown ? (value: T) => void : never) extends (value: infer TIntersection) => void ? TIntersection : never;
72
- export declare const contract: typeof defineContract;
73
- type ProtocolDispatchEntries<TProcedures extends Record<string, ProcedureDefinition>> = {
74
- [TProcedure in keyof TProcedures & string]: {
75
- [TProtocol in keyof TProcedures[TProcedure]['protocols'] & string]: TProcedures[TProcedure]['protocols'][TProtocol] extends {
76
- readonly dispatchKey: infer TDispatchKey extends string | null;
77
- } ? TDispatchKey extends string ? {
78
- readonly key: TDispatchKey;
79
- readonly path: `${TProcedure}.${TProtocol}`;
80
- } : never : never;
81
- }[keyof TProcedures[TProcedure]['protocols'] & string];
82
- }[keyof TProcedures & string];
83
- type IsUnion<TValue, TCandidate = TValue> = TValue extends unknown ? [TCandidate] extends [TValue] ? false : true : never;
84
- type DuplicateDispatchKeys<TEntries, TAllEntries = TEntries> = TEntries extends {
85
- readonly key: infer TKey extends string;
86
- } ? string extends TKey ? never : IsUnion<Extract<TAllEntries, {
87
- readonly key: TKey;
88
- }> extends {
89
- readonly path: infer TPath;
90
- } ? TPath : never> extends true ? TKey : never : never;
91
- export type ContractProcedures<TContract extends ContractDefinition> = TContract['procedures'];
92
- export interface ProtocolFactory<TName extends string, TCapabilities extends readonly string[] = readonly string[]> {
93
- readonly protocol: TName;
94
- readonly capabilities?: TCapabilities;
95
- }
96
- export {};
@@ -1,88 +0,0 @@
1
- import { contractNodeBinding, contractNodeKindType, protocolNamespaceBuilder, protocolNamespaceType, } from './contract-internal.js';
2
- export function protocolGroup(protocol, procedures) {
3
- return Object.freeze({
4
- kind: 'protocol-group',
5
- protocol,
6
- procedures: Object.freeze({ ...procedures }),
7
- });
8
- }
9
- function defineContract(groups, ..._validation) {
10
- if (groups.length === 0) {
11
- throw new Error('contract([]) requires at least one protocol group');
12
- }
13
- const procedures = {};
14
- for (const group of groups) {
15
- for (const [procedureName, descriptor] of Object.entries(group.procedures)) {
16
- const current = procedures[procedureName];
17
- if (Object.hasOwn(current?.protocols ?? {}, group.protocol)) {
18
- throw new Error(`Duplicate contract procedure protocol: ${procedureName}.${group.protocol}`);
19
- }
20
- procedures[procedureName] = {
21
- kind: 'procedure',
22
- protocols: {
23
- ...current?.protocols,
24
- [group.protocol]: descriptor,
25
- },
26
- };
27
- }
28
- }
29
- assertUniqueDispatchKeys(procedures);
30
- const resolved = {
31
- kind: 'contract',
32
- procedures: Object.freeze(procedures),
33
- };
34
- const namespaceBuilders = [];
35
- for (const group of groups) {
36
- const build = group[protocolNamespaceBuilder];
37
- if (typeof build !== 'function')
38
- continue;
39
- namespaceBuilders.push({
40
- protocol: group.protocol,
41
- build: build,
42
- });
43
- }
44
- applyProtocolNamespaces(resolved, namespaceBuilders);
45
- return Object.freeze(resolved);
46
- }
47
- function applyProtocolNamespaces(resolved, builders) {
48
- for (const { protocol, build } of builders) {
49
- const namespace = build(resolved);
50
- const current = resolved[protocol];
51
- if (current === undefined) {
52
- resolved[protocol] = namespace;
53
- continue;
54
- }
55
- if (!isRecord(current) || !isRecord(namespace)) {
56
- throw new Error(`Duplicate contract protocol namespace: ${protocol}`);
57
- }
58
- for (const name of Object.keys(namespace)) {
59
- if (Object.hasOwn(current, name)) {
60
- throw new Error(`Duplicate contract protocol namespace node: ${protocol}.${name}`);
61
- }
62
- }
63
- resolved[protocol] = Object.freeze({ ...current, ...namespace });
64
- }
65
- }
66
- function isRecord(value) {
67
- return typeof value === 'object' && value !== null && !Array.isArray(value);
68
- }
69
- export const contract = defineContract;
70
- function assertUniqueDispatchKeys(procedures) {
71
- const paths = new Map();
72
- for (const [procedureName, procedureDefinition] of Object.entries(procedures)) {
73
- for (const [protocolName, protocol] of Object.entries(procedureDefinition.protocols)) {
74
- const dispatchKey = protocol.dispatchKey;
75
- if (dispatchKey === null)
76
- continue;
77
- if (typeof dispatchKey !== 'string') {
78
- throw new Error(`Protocol dispatchKey must be a string or null: ${procedureName}.${protocolName}`);
79
- }
80
- const path = `${procedureName}.${protocolName}`;
81
- const existing = paths.get(dispatchKey);
82
- if (existing) {
83
- throw new Error(`Duplicate protocol dispatch key "${dispatchKey}" between ${existing} and ${path}`);
84
- }
85
- paths.set(dispatchKey, path);
86
- }
87
- }
88
- }
@@ -1,78 +0,0 @@
1
- import { type SchemaOutput, type StandardSchemaV1 } from './schema.js';
2
- import { type Token } from './token.js';
3
- export type TaskRuntime<TInput, TOutput> = [TInput] extends [void] ? () => TOutput | Promise<TOutput> : (input: TInput) => TOutput | Promise<TOutput>;
4
- export interface TaskDescriptor<TInput = unknown, TOutput = unknown, TName extends string = string> {
5
- readonly kind: 'task';
6
- readonly name: TName;
7
- readonly factory: () => TaskRuntime<TInput, TOutput>;
8
- }
9
- export type TaskInput<T> = T extends TaskDescriptor<infer TInput, any, any> ? TInput : never;
10
- export type TaskOutput<T> = T extends TaskDescriptor<any, infer TOutput, any> ? TOutput : never;
11
- export type TaskArguments<T> = [TaskInput<T>] extends [void] ? readonly [] : readonly [input: TaskInput<T>];
12
- export declare function task<TInput = void, TOutput = void, const TName extends string = string>(declaration: {
13
- readonly name: TName;
14
- readonly factory: () => TaskRuntime<TInput, TOutput>;
15
- }): TaskDescriptor<TInput, TOutput, TName>;
16
- type VoidTaskConstraint<TTask> = [TaskInput<TTask>] extends [void] ? unknown : never;
17
- export type CronOverlap = 'allow' | 'skip';
18
- export interface CronTriggerDescriptor<TTask extends TaskDescriptor<void, any> = TaskDescriptor<void, any>, TName extends string = string> {
19
- readonly kind: 'trigger';
20
- readonly trigger: 'cron';
21
- readonly name: TName;
22
- readonly expression: string;
23
- readonly timezone: string;
24
- readonly overlap: CronOverlap;
25
- readonly task: TTask;
26
- }
27
- export declare function cron<const TTask extends TaskDescriptor<any, any>, const TName extends string>(declaration: {
28
- readonly name: TName;
29
- readonly expression: string;
30
- readonly timezone: string;
31
- readonly overlap?: CronOverlap;
32
- readonly task: TTask;
33
- } & VoidTaskConstraint<TTask>): CronTriggerDescriptor<TTask & TaskDescriptor<void, any>, TName>;
34
- export interface FixedDelayTriggerDescriptor<TTask extends TaskDescriptor<void, any> = TaskDescriptor<void, any>, TName extends string = string> {
35
- readonly kind: 'trigger';
36
- readonly trigger: 'fixed-delay';
37
- readonly name: TName;
38
- readonly delay: number;
39
- readonly immediate: boolean;
40
- readonly task: TTask;
41
- }
42
- export declare function fixedDelay<const TTask extends TaskDescriptor<any, any>, const TName extends string>(declaration: {
43
- readonly name: TName;
44
- readonly delay: number;
45
- readonly immediate?: boolean;
46
- readonly task: TTask;
47
- } & VoidTaskConstraint<TTask>): FixedDelayTriggerDescriptor<TTask & TaskDescriptor<void, any>, TName>;
48
- declare const queueDriverToken: unique symbol;
49
- export interface QueueDescriptor<TSchema extends StandardSchemaV1 = StandardSchemaV1, TName extends string = string> {
50
- readonly kind: 'queue';
51
- readonly name: TName;
52
- readonly payload: TSchema;
53
- readonly [queueDriverToken]: Token<unknown>;
54
- }
55
- export type QueuePayload<T> = T extends QueueDescriptor<infer TSchema, any> ? SchemaOutput<TSchema> : never;
56
- export declare function queue<const TSchema extends StandardSchemaV1, const TName extends string = string>(declaration: {
57
- readonly name: TName;
58
- readonly payload: TSchema;
59
- }): QueueDescriptor<TSchema, TName>;
60
- export declare function queueRuntimeToken(descriptor: QueueDescriptor): Token<unknown>;
61
- export interface QueueConsumerTriggerDescriptor<TQueue extends QueueDescriptor<any> = QueueDescriptor<any>, TTask extends TaskDescriptor<any, any> = TaskDescriptor<any, any>, TName extends string = string> {
62
- readonly kind: 'trigger';
63
- readonly trigger: 'queue-consumer';
64
- readonly name: TName;
65
- readonly queue: TQueue;
66
- readonly task: TTask;
67
- }
68
- type ConsumerTaskConstraint<TQueue, TTask> = [TaskInput<TTask>] extends [
69
- QueuePayload<TQueue>
70
- ] ? [QueuePayload<TQueue>] extends [TaskInput<TTask>] ? unknown : never : never;
71
- export declare function consume<const TQueue extends QueueDescriptor<any>, const TTask extends TaskDescriptor<any, any>, const TName extends string>(declaration: {
72
- readonly name: TName;
73
- readonly queue: TQueue;
74
- readonly task: TTask;
75
- } & ConsumerTaskConstraint<TQueue, TTask>): QueueConsumerTriggerDescriptor<TQueue, TTask & TaskDescriptor<QueuePayload<TQueue>, any>, TName>;
76
- export type TriggerDescriptor = CronTriggerDescriptor<any, any> | FixedDelayTriggerDescriptor<any, any> | QueueConsumerTriggerDescriptor<any, any, any>;
77
- export type TriggerTask<TTrigger> = TTrigger extends TriggerDescriptor ? TTrigger['task'] : never;
78
- export {};
@@ -1,61 +0,0 @@
1
- import { token } from './token.js';
2
- export function task(declaration) {
3
- return Object.freeze({
4
- kind: 'task',
5
- name: declaration.name,
6
- factory: declaration.factory,
7
- });
8
- }
9
- export function cron(declaration) {
10
- return Object.freeze({
11
- kind: 'trigger',
12
- trigger: 'cron',
13
- name: declaration.name,
14
- expression: declaration.expression,
15
- timezone: declaration.timezone,
16
- overlap: declaration.overlap ?? 'skip',
17
- task: declaration.task,
18
- });
19
- }
20
- export function fixedDelay(declaration) {
21
- if (!Number.isFinite(declaration.delay) ||
22
- !Number.isInteger(declaration.delay) ||
23
- declaration.delay < 0) {
24
- throw new Error('LUTRE_TRIGGER_INVALID_FIXED_DELAY: fixedDelay.delay must be a non-negative finite integer.');
25
- }
26
- return Object.freeze({
27
- kind: 'trigger',
28
- trigger: 'fixed-delay',
29
- name: declaration.name,
30
- delay: declaration.delay,
31
- immediate: declaration.immediate ?? false,
32
- task: declaration.task,
33
- });
34
- }
35
- const queueDriverToken = Symbol('loutre.queue-driver');
36
- export function queue(declaration) {
37
- const payload = declaration.payload;
38
- if (payload === null ||
39
- (typeof payload !== 'object' && typeof payload !== 'function') ||
40
- !('~standard' in payload)) {
41
- throw new Error('LUTRE_QUEUE_PAYLOAD_SCHEMA: queue.payload must implement Standard Schema.');
42
- }
43
- return Object.freeze({
44
- kind: 'queue',
45
- name: declaration.name,
46
- payload: declaration.payload,
47
- [queueDriverToken]: token(`loutre.queue-driver.${declaration.name}`),
48
- });
49
- }
50
- export function queueRuntimeToken(descriptor) {
51
- return descriptor[queueDriverToken];
52
- }
53
- export function consume(declaration) {
54
- return Object.freeze({
55
- kind: 'trigger',
56
- trigger: 'queue-consumer',
57
- name: declaration.name,
58
- queue: declaration.queue,
59
- task: declaration.task,
60
- });
61
- }
@@ -1,44 +0,0 @@
1
- import type { ContractDefinition, ContractOfBinding, ResolvedContractNode, ContractProcedures, ProtocolDescriptor, ProtocolFactory } from './contract.js';
2
- type ImplementationBinding = ContractDefinition | ResolvedContractNode<ContractDefinition, 'leaf'>;
3
- type ProcedureNamesForProtocol<TBinding extends ImplementationBinding, TProtocol extends string, TContract extends ContractDefinition = ContractOfBinding<TBinding>> = {
4
- [K in keyof ContractProcedures<TContract>]: TProtocol extends keyof ContractProcedures<TContract>[K]['protocols'] ? K : never;
5
- }[keyof ContractProcedures<TContract>] & string;
6
- type ImplementationRuntimeShape<TBinding extends ImplementationBinding, TProtocol extends string, TProcedures extends string, TContract extends ContractDefinition = ContractOfBinding<TBinding>> = {
7
- [K in TProcedures]: ContractProcedures<TContract>[K]['protocols'][TProtocol & keyof ContractProcedures<TContract>[K]['protocols']] extends ProtocolDescriptor<TProtocol, infer TContext, infer TResult, any, any> ? (context: TContext) => TResult | Promise<TResult> : never;
8
- };
9
- export interface ImplementationDescriptor<TContract extends ContractDefinition = ContractDefinition, TProtocol extends string = string, TProcedures extends readonly string[] = readonly string[], TRuntime extends object = object, TCapabilities extends readonly string[] = readonly string[]> {
10
- readonly kind: 'implementation';
11
- readonly name: string;
12
- readonly contract: TContract;
13
- readonly protocol: TProtocol;
14
- readonly capabilities: TCapabilities;
15
- readonly procedures: TProcedures;
16
- readonly factory: () => TRuntime;
17
- }
18
- type AvailableProtocolConstraint<TBinding extends ImplementationBinding, TProtocol extends string, TCapabilities extends readonly string[]> = [ProcedureNamesForProtocol<TBinding, TProtocol>] extends [never] ? never : ProtocolFactory<TProtocol, TCapabilities>;
19
- type FullImplementationDeclaration<TBinding extends ImplementationBinding, TProtocol extends string, TCapabilities extends readonly string[]> = {
20
- readonly name: string;
21
- readonly contract: TBinding;
22
- readonly protocol: AvailableProtocolConstraint<TBinding, TProtocol, TCapabilities>;
23
- readonly procedures?: never;
24
- readonly factory: () => ImplementationRuntimeShape<TBinding, TProtocol, ProcedureNamesForProtocol<TBinding, TProtocol>>;
25
- };
26
- type DuplicateProcedureNames<TProcedures extends readonly string[], TSeen extends string = never> = number extends TProcedures['length'] ? never : TProcedures extends readonly [
27
- infer THead extends string,
28
- ...infer TTail extends readonly string[]
29
- ] ? THead extends TSeen ? THead | DuplicateProcedureNames<TTail, TSeen> : DuplicateProcedureNames<TTail, TSeen | THead> : never;
30
- type UniqueProcedureSelectionConstraint<TProcedures extends readonly string[]> = [
31
- DuplicateProcedureNames<TProcedures>
32
- ] extends [never] ? unknown : {
33
- readonly __duplicateImplementationProcedure__: never;
34
- };
35
- type PartialImplementationDeclaration<TBinding extends ImplementationBinding, TProtocol extends string, TProcedures extends readonly ProcedureNamesForProtocol<TBinding, TProtocol>[], TCapabilities extends readonly string[]> = {
36
- readonly name: string;
37
- readonly contract: TBinding;
38
- readonly protocol: AvailableProtocolConstraint<TBinding, TProtocol, TCapabilities>;
39
- readonly procedures: TProcedures & UniqueProcedureSelectionConstraint<TProcedures>;
40
- readonly factory: () => ImplementationRuntimeShape<TBinding, TProtocol, TProcedures[number]>;
41
- };
42
- export declare function implementation<const TBinding extends ImplementationBinding, const TProtocol extends string, const TCapabilities extends readonly string[]>(declaration: FullImplementationDeclaration<TBinding, TProtocol, TCapabilities>): ImplementationDescriptor<ContractOfBinding<TBinding>, TProtocol, readonly ProcedureNamesForProtocol<TBinding, TProtocol>[], ImplementationRuntimeShape<TBinding, TProtocol, ProcedureNamesForProtocol<TBinding, TProtocol>>, TCapabilities>;
43
- export declare function implementation<const TBinding extends ImplementationBinding, const TProtocol extends string, const TProcedures extends readonly ProcedureNamesForProtocol<TBinding, TProtocol>[], const TCapabilities extends readonly string[]>(declaration: PartialImplementationDeclaration<TBinding, TProtocol, TProcedures, TCapabilities>): ImplementationDescriptor<ContractOfBinding<TBinding>, TProtocol, TProcedures, ImplementationRuntimeShape<TBinding, TProtocol, TProcedures[number]>, TCapabilities>;
44
- export {};
@@ -1,35 +0,0 @@
1
- import { contractNodeMetadataOf, contractOfBinding, } from './contract-internal.js';
2
- export function implementation(declaration) {
3
- const protocol = declaration.protocol.protocol;
4
- const contract = contractOfBinding(declaration.contract);
5
- if (contractNodeMetadataOf(contract)?.kind === 'branch') {
6
- throw new Error('LUTRE_IMPL_003: Implementation must bind to a resolved leaf Contract node.');
7
- }
8
- const available = Object.entries(contract.procedures)
9
- .filter(([, procedure]) => protocol in procedure.protocols)
10
- .map(([name]) => name);
11
- if (available.length === 0) {
12
- throw new Error(`LUTRE_IMPL_003: Contract does not declare any procedure for protocol ${protocol}.`);
13
- }
14
- const procedures = [...(declaration.procedures ?? available)];
15
- const selected = new Set();
16
- for (const procedure of procedures) {
17
- if (selected.has(procedure)) {
18
- throw new Error(`LUTRE_IMPL_003: Implementation ${declaration.name} selects procedure ${procedure} more than once.`);
19
- }
20
- selected.add(procedure);
21
- const definition = contract.procedures[procedure];
22
- if (!definition || !(protocol in definition.protocols)) {
23
- throw new Error(`LUTRE_IMPL_003: ${procedure} is not declared for protocol ${protocol}.`);
24
- }
25
- }
26
- return Object.freeze({
27
- kind: 'implementation',
28
- name: declaration.name,
29
- contract,
30
- protocol,
31
- capabilities: declaration.protocol.capabilities ?? [],
32
- procedures: Object.freeze(procedures),
33
- factory: declaration.factory,
34
- });
35
- }
@@ -1,137 +0,0 @@
1
- import type { ContextKey, ContextProperties } from './context-key.js';
2
- export type LayerRole = 'generic' | 'authentication' | 'guard' | 'validation' | 'framework' | 'terminal';
3
- export type ValidatedInputPart = 'params' | 'query' | 'headers' | 'body';
4
- declare const shortCircuitMarker: unique symbol;
5
- export interface ShortCircuit<TResult = unknown> {
6
- readonly kind: 'short-circuit';
7
- readonly result: TResult;
8
- readonly [shortCircuitMarker]: true;
9
- }
10
- export declare function shortCircuit<const TResult>(result: TResult): ShortCircuit<TResult>;
11
- export declare function isShortCircuit(value: unknown): value is ShortCircuit;
12
- declare const shortCircuitResultType: unique symbol;
13
- export interface ShortCircuitDeclaration {
14
- readonly protocol: string;
15
- readonly variant: string;
16
- readonly response?: Readonly<Record<string, unknown>>;
17
- }
18
- export type LayerNext<TProvides extends readonly ContextKey[]> = number extends TProvides['length'] ? (provided: ContextProperties<TProvides>) => Promise<void> : TProvides extends readonly [] ? () => Promise<void> : (provided: ContextProperties<TProvides>) => Promise<void>;
19
- export type LayerRuntime<TContext extends object, TProvides extends readonly ContextKey[], TShortCircuitResult> = (context: TContext, next: LayerNext<TProvides>) => Promise<void | ShortCircuit<TShortCircuitResult>>;
20
- export type LayerFactory<TContext extends object, TProvides extends readonly ContextKey[], TShortCircuitResult> = () => LayerRuntime<TContext, TProvides, TShortCircuitResult>;
21
- export interface LayerDefinition<TRequires extends readonly ContextKey[] = readonly [], TProvides extends readonly ContextKey[] = readonly [], TContext extends object = {}, TShortCircuitResult = never, TShortCircuits extends readonly ShortCircuitDeclaration[] = readonly [], TName extends string = string, TRole extends Exclude<LayerRole, 'terminal' | 'validation'> = 'generic', TRequiresValidated extends readonly ValidatedInputPart[] = readonly []> {
22
- readonly name: TName;
23
- readonly role?: TRole;
24
- readonly requires?: TRequires;
25
- readonly provides?: TProvides;
26
- readonly requiresValidated?: TRequiresValidated;
27
- readonly shortCircuits?: TShortCircuits;
28
- readonly factory: LayerFactory<TContext & ContextProperties<TRequires>, TProvides, TShortCircuitResult>;
29
- }
30
- export interface LayerOccurrenceDescriptor<TRequires extends readonly ContextKey[] = readonly ContextKey[], TProvides extends readonly ContextKey[] = readonly ContextKey[], TShortCircuitResult = unknown, TShortCircuits extends readonly ShortCircuitDeclaration[] = readonly ShortCircuitDeclaration[], TName extends string = string, TRole extends Exclude<LayerRole, 'terminal' | 'validation'> = Exclude<LayerRole, 'terminal' | 'validation'>, TRequiresValidated extends readonly ValidatedInputPart[] = readonly ValidatedInputPart[], TContext extends object = object, TPipeline extends readonly PipelineItem[] = readonly PipelineItem[]> {
31
- readonly kind: 'layer';
32
- readonly name: TName;
33
- readonly role: TRole;
34
- readonly requires: TRequires;
35
- readonly provides: TProvides;
36
- readonly requiresValidated: TRequiresValidated;
37
- readonly shortCircuits: TShortCircuits;
38
- readonly definition: LayerDescriptor<TRequires, TProvides, TShortCircuitResult, TShortCircuits, TName, TRole, TRequiresValidated, TContext>;
39
- readonly pipeline: TPipeline;
40
- readonly factory?: never;
41
- readonly [shortCircuitResultType]?: TShortCircuitResult;
42
- }
43
- export interface LayerDescriptor<TRequires extends readonly ContextKey[] = readonly ContextKey[], TProvides extends readonly ContextKey[] = readonly ContextKey[], TShortCircuitResult = unknown, TShortCircuits extends readonly ShortCircuitDeclaration[] = readonly ShortCircuitDeclaration[], TName extends string = string, TRole extends Exclude<LayerRole, 'terminal' | 'validation'> = Exclude<LayerRole, 'terminal' | 'validation'>, TRequiresValidated extends readonly ValidatedInputPart[] = readonly ValidatedInputPart[], TContext extends object = object> {
44
- <const TPipeline extends readonly PipelineItem[]>(pipeline: TPipeline): LayerOccurrenceDescriptor<TRequires, TProvides, TShortCircuitResult, TShortCircuits, TName, TRole, TRequiresValidated, TContext, TPipeline>;
45
- readonly kind: 'layer';
46
- readonly name: TName;
47
- readonly role: TRole;
48
- readonly requires: TRequires;
49
- readonly provides: TProvides;
50
- readonly requiresValidated: TRequiresValidated;
51
- readonly shortCircuits: TShortCircuits;
52
- readonly factory: LayerFactory<TContext & ContextProperties<TRequires>, TProvides, TShortCircuitResult>;
53
- readonly definition?: never;
54
- readonly pipeline?: never;
55
- readonly [shortCircuitResultType]?: TShortCircuitResult;
56
- }
57
- export interface ValidationLayerDescriptor {
58
- readonly kind: 'validation';
59
- readonly name: `validate.${'params' | 'query' | 'headers' | 'body'}`;
60
- readonly role: 'validation';
61
- readonly part: 'params' | 'query' | 'headers' | 'body';
62
- }
63
- export interface TerminalLayerDescriptor<TProtocol extends string = string> {
64
- readonly kind: 'terminal';
65
- readonly name: `${TProtocol}.${string}`;
66
- readonly role: 'terminal';
67
- readonly protocol: TProtocol;
68
- }
69
- type AnyLayerDescriptor = LayerDescriptor<any, any, any, any, any, any, any, any>;
70
- type AnyLayerOccurrence = LayerOccurrenceDescriptor<any, any, any, any, any, any, any, any, any>;
71
- export type PipelineItem = AnyLayerDescriptor | AnyLayerOccurrence | ValidationLayerDescriptor | TerminalLayerDescriptor;
72
- export declare function isLayerOccurrence(item: PipelineItem): item is AnyLayerOccurrence;
73
- export declare function layerDefinitionOf(item: AnyLayerDescriptor | AnyLayerOccurrence): AnyLayerDescriptor;
74
- export declare function childPipelineOf(item: AnyLayerDescriptor | AnyLayerOccurrence): readonly PipelineItem[] | undefined;
75
- interface PipelineTerminalState<THasTerminal extends boolean, TValid extends boolean> {
76
- readonly hasTerminal: THasTerminal;
77
- readonly valid: TValid;
78
- }
79
- type InvalidPipelineTerminalState = PipelineTerminalState<boolean, false>;
80
- type FoldPipelineTerminals<TPipeline extends readonly PipelineItem[], TProtocol extends string, TState extends PipelineTerminalState<boolean, boolean>> = TState['valid'] extends false ? TState : number extends TPipeline['length'] ? InvalidPipelineTerminalState : TPipeline extends readonly [infer THead, ...infer TTail] ? TState['hasTerminal'] extends true ? InvalidPipelineTerminalState : FoldPipelineTerminals<Extract<TTail, readonly PipelineItem[]>, TProtocol, FoldPipelineItemTerminals<THead, TProtocol, TState>> : TState;
81
- type FoldPipelineItemTerminals<TItem, TProtocol extends string, TState extends PipelineTerminalState<boolean, boolean>> = TItem extends TerminalLayerDescriptor<infer TItemProtocol> ? [TItemProtocol, TProtocol] extends [TProtocol, TItemProtocol] ? PipelineTerminalState<true, true> : InvalidPipelineTerminalState : TItem extends LayerOccurrenceDescriptor<any, any, any, any, any, any, any, any, infer TPipeline> ? FoldPipelineTerminals<TPipeline, TProtocol, TState> : TState;
82
- type ContextKeyNameOf<TKey> = TKey extends ContextKey<infer TName, any> ? TName : never;
83
- type ContextKeyNamesOf<TKeys extends readonly ContextKey[]> = ContextKeyNameOf<TKeys[number]>;
84
- type DuplicateContextKeyNames<TKeys extends readonly ContextKey[], TSeen extends string = never> = number extends TKeys['length'] ? never : TKeys extends readonly [
85
- infer THead extends ContextKey,
86
- ...infer TTail extends readonly ContextKey[]
87
- ] ? ContextKeyNameOf<THead> extends infer TName extends string ? TName extends TSeen ? TName | DuplicateContextKeyNames<TTail, TSeen> : DuplicateContextKeyNames<TTail, TSeen | TName> : never : never;
88
- type AreRequiredContextKeysAvailable<TRequires extends readonly ContextKey[], TAvailable extends ContextKey> = [TRequires[number]] extends [never] ? true : false extends (TRequires[number] extends infer TRequired extends ContextKey ? TRequired extends TAvailable ? true : false : never) ? false : true;
89
- type AreRequiredValidatedPartsAvailable<TRequires extends readonly ValidatedInputPart[], TValidated extends ValidatedInputPart> = Exclude<TRequires[number], TValidated> extends never ? true : false;
90
- type HasProvidedContextCollision<TProvides extends readonly ContextKey[], TAvailable extends ContextKey> = DuplicateContextKeyNames<TProvides> | Extract<ContextKeyNamesOf<TProvides>, ContextKeyNameOf<TAvailable>> extends never ? false : true;
91
- interface PipelineRequirementState<TAvailable extends ContextKey, TValidated extends ValidatedInputPart, TValid extends boolean> {
92
- readonly available: TAvailable;
93
- readonly validated: TValidated;
94
- readonly valid: TValid;
95
- }
96
- type InvalidPipelineRequirementState = PipelineRequirementState<ContextKey, ValidatedInputPart, false>;
97
- type FoldLayerRequirements<TRequires extends readonly ContextKey[], TProvides extends readonly ContextKey[], TRequiresValidated extends readonly ValidatedInputPart[], TState extends PipelineRequirementState<ContextKey, ValidatedInputPart, boolean>> = TState['valid'] extends false ? TState : AreRequiredContextKeysAvailable<TRequires, TState['available']> extends true ? AreRequiredValidatedPartsAvailable<TRequiresValidated, TState['validated']> extends true ? HasProvidedContextCollision<TProvides, TState['available']> extends false ? PipelineRequirementState<TState['available'] | TProvides[number], TState['validated'], true> : InvalidPipelineRequirementState : InvalidPipelineRequirementState : InvalidPipelineRequirementState;
98
- type FoldPipelineRequirements<TPipeline extends readonly PipelineItem[], TState extends PipelineRequirementState<ContextKey, ValidatedInputPart, boolean>> = TState['valid'] extends false ? TState : number extends TPipeline['length'] ? TState : TPipeline extends readonly [infer THead, ...infer TTail] ? FoldPipelineRequirements<Extract<TTail, readonly PipelineItem[]>, FoldPipelineItemRequirements<THead, TState>> : TState;
99
- type FoldPipelineItemRequirements<TItem, TState extends PipelineRequirementState<ContextKey, ValidatedInputPart, boolean>> = TItem extends ValidationLayerDescriptor ? PipelineRequirementState<TState['available'], TState['validated'] | TItem['part'], TState['valid']> : TItem extends LayerOccurrenceDescriptor<infer TRequires, infer TProvides, any, any, any, any, infer TRequiresValidated, any, infer TPipeline> ? FoldPipelineRequirements<TPipeline, FoldLayerRequirements<TRequires, TProvides, TRequiresValidated, TState>> : TItem extends LayerDescriptor<infer TRequires, infer TProvides, any, any, any, any, infer TRequiresValidated, any> ? FoldLayerRequirements<TRequires, TProvides, TRequiresValidated, TState> : TState;
100
- type IsPipelineRequirementsValid<TPipeline extends readonly PipelineItem[]> = FoldPipelineRequirements<TPipeline, PipelineRequirementState<never, never, true>>['valid'] extends true ? true : false;
101
- export type IsValidProtocolPipeline<TPipeline extends readonly PipelineItem[], TProtocol extends string> = FoldPipelineTerminals<TPipeline, TProtocol, PipelineTerminalState<false, true>> extends PipelineTerminalState<true, true> ? IsPipelineRequirementsValid<TPipeline> : false;
102
- export type ShortCircuitResultOf<TItem> = TItem extends LayerOccurrenceDescriptor<any, any, any, any, any, any, any, any, infer TPipeline> ? ShortCircuitResultOfPipeline<TPipeline> | ShortCircuitResultOfLayer<TItem> : ShortCircuitResultOfLayer<TItem>;
103
- type ShortCircuitResultOfLayer<TItem> = TItem extends {
104
- readonly [shortCircuitResultType]?: infer TResult;
105
- } ? TResult : never;
106
- export type ShortCircuitDeclarationsOf<TItem> = TItem extends LayerOccurrenceDescriptor<any, any, any, any, any, any, any, any, infer TPipeline> ? readonly [
107
- ...NormalizeDeclarations<TItem['shortCircuits']>,
108
- ...ShortCircuitDeclarationsOfPipeline<TPipeline>
109
- ] : TItem extends {
110
- readonly shortCircuits: infer TShortCircuits;
111
- } ? TShortCircuits : never;
112
- type ShortCircuitResultOfPipeline<TPipeline extends readonly PipelineItem[]> = TPipeline[number] extends infer TItem ? ShortCircuitResultOf<TItem> : never;
113
- type ShortCircuitDeclarationsOfPipeline<TPipeline extends readonly PipelineItem[]> = TPipeline extends readonly [infer THead, ...infer TTail] ? readonly [
114
- ...NormalizeDeclarations<ShortCircuitDeclarationsOf<THead>>,
115
- ...ShortCircuitDeclarationsOfPipeline<Extract<TTail, readonly PipelineItem[]>>
116
- ] : readonly [];
117
- type NormalizeDeclarations<TDeclarations> = TDeclarations extends readonly ShortCircuitDeclaration[] ? TDeclarations : readonly [];
118
- interface PipelineTypeState<TContext extends object, TValidated extends ValidatedInputPart, TDone extends boolean> {
119
- readonly context: TContext;
120
- readonly validated: TValidated;
121
- readonly done: TDone;
122
- }
123
- type FoldPipeline<TPipeline extends readonly PipelineItem[], TState extends PipelineTypeState<object, ValidatedInputPart, boolean>> = TState['done'] extends true ? TState : number extends TPipeline['length'] ? TState : TPipeline extends readonly [infer THead, ...infer TTail] ? FoldPipeline<Extract<TTail, readonly PipelineItem[]>, FoldPipelineItem<THead, TState>> : TState;
124
- type FoldPipelineItem<TItem, TState extends PipelineTypeState<object, ValidatedInputPart, boolean>> = TItem extends TerminalLayerDescriptor ? PipelineTypeState<TState['context'], TState['validated'], true> : TItem extends ValidationLayerDescriptor ? PipelineTypeState<TState['context'], TState['validated'] | TItem['part'], false> : TItem extends LayerOccurrenceDescriptor<any, infer TProvides, any, any, any, any, any, any, infer TPipeline> ? FoldPipeline<TPipeline, PipelineTypeState<TState['context'] & ContextProperties<TProvides>, TState['validated'], false>> : TItem extends LayerDescriptor<any, infer TProvides, any, any, any, any, any, any> ? PipelineTypeState<TState['context'] & ContextProperties<TProvides>, TState['validated'], false> : TState;
125
- export type ContextProvidedBeforeTerminal<TPipeline extends readonly PipelineItem[], TContext extends object = {}> = number extends TPipeline['length'] ? TContext : FoldPipeline<TPipeline, PipelineTypeState<TContext, never, false>>['context'];
126
- export type HasValidationBeforeTerminal<TPipeline extends readonly PipelineItem[], TPart extends ValidatedInputPart> = number extends TPipeline['length'] ? false : TPart extends FoldPipeline<TPipeline, PipelineTypeState<{}, never, false>>['validated'] ? true : false;
127
- type DuplicateValidatedInputParts<TParts extends readonly ValidatedInputPart[], TSeen extends ValidatedInputPart = never> = number extends TParts['length'] ? never : TParts extends readonly [
128
- infer THead extends ValidatedInputPart,
129
- ...infer TTail extends readonly ValidatedInputPart[]
130
- ] ? THead extends TSeen ? THead | DuplicateValidatedInputParts<TTail, TSeen> : DuplicateValidatedInputParts<TTail, TSeen | THead> : never;
131
- type LayerDefinitionConstraint<TRequires extends readonly ContextKey[], TProvides extends readonly ContextKey[], TRequiresValidated extends readonly ValidatedInputPart[]> = [
132
- DuplicateContextKeyNames<TRequires> | DuplicateContextKeyNames<TProvides> | Extract<ContextKeyNamesOf<TRequires>, ContextKeyNamesOf<TProvides>> | DuplicateValidatedInputParts<TRequiresValidated>
133
- ] extends [never] ? unknown : {
134
- readonly __invalidLayerDefinition__: never;
135
- };
136
- export declare function layer<const TRequires extends readonly ContextKey[] = readonly [], const TProvides extends readonly ContextKey[] = readonly [], TContext extends object = {}, TShortCircuitResult = never, const TShortCircuits extends readonly ShortCircuitDeclaration[] = readonly [], const TName extends string = string, const TRole extends Exclude<LayerRole, 'terminal' | 'validation'> = 'generic', const TRequiresValidated extends readonly ValidatedInputPart[] = readonly []>(definition: LayerDefinition<TRequires, TProvides, TContext, TShortCircuitResult, TShortCircuits, TName, TRole, TRequiresValidated> & LayerDefinitionConstraint<TRequires, TProvides, TRequiresValidated>): LayerDescriptor<TRequires, TProvides, TShortCircuitResult, TShortCircuits, TName, TRole, TRequiresValidated, TContext>;
137
- export {};
@@ -1,81 +0,0 @@
1
- const shortCircuitMarker = Symbol('loutre.short-circuit');
2
- export function shortCircuit(result) {
3
- return {
4
- kind: 'short-circuit',
5
- result,
6
- [shortCircuitMarker]: true,
7
- };
8
- }
9
- export function isShortCircuit(value) {
10
- return (typeof value === 'object' &&
11
- value !== null &&
12
- shortCircuitMarker in value &&
13
- value[shortCircuitMarker] === true);
14
- }
15
- export function isLayerOccurrence(item) {
16
- return item.kind === 'layer' && item.definition !== undefined;
17
- }
18
- export function layerDefinitionOf(item) {
19
- return isLayerOccurrence(item) ? item.definition : item;
20
- }
21
- export function childPipelineOf(item) {
22
- return isLayerOccurrence(item) ? item.pipeline : undefined;
23
- }
24
- function assertUniqueContextKeyNames(keys, label) {
25
- const names = new Set();
26
- for (const key of keys) {
27
- if (names.has(key.name)) {
28
- throw new Error(`Layer ${label} contains duplicate Context property ${key.name}`);
29
- }
30
- names.add(key.name);
31
- }
32
- }
33
- function assertLayerDefinition(definition) {
34
- const requires = definition.requires ?? [];
35
- const provides = definition.provides ?? [];
36
- assertUniqueContextKeyNames(requires, 'requires');
37
- assertUniqueContextKeyNames(provides, 'provides');
38
- const requiredNames = new Set(requires.map((key) => key.name));
39
- for (const key of provides) {
40
- if (requiredNames.has(key.name)) {
41
- throw new Error(`Layer cannot require and provide the same Context property ${key.name}`);
42
- }
43
- }
44
- const validated = new Set();
45
- for (const part of definition.requiresValidated ?? []) {
46
- if (validated.has(part)) {
47
- throw new Error(`Layer requiresValidated contains duplicate part ${part}`);
48
- }
49
- validated.add(part);
50
- }
51
- }
52
- export function layer(definition) {
53
- assertLayerDefinition(definition);
54
- let descriptor;
55
- const callable = (pipeline) => Object.freeze({
56
- kind: 'layer',
57
- name: descriptor.name,
58
- role: descriptor.role,
59
- requires: descriptor.requires,
60
- provides: descriptor.provides,
61
- requiresValidated: descriptor.requiresValidated,
62
- shortCircuits: descriptor.shortCircuits,
63
- definition: descriptor,
64
- pipeline,
65
- });
66
- Object.defineProperty(callable, 'name', {
67
- value: definition.name,
68
- enumerable: true,
69
- configurable: true,
70
- });
71
- descriptor = Object.assign(callable, {
72
- kind: 'layer',
73
- role: definition.role ?? 'generic',
74
- requires: definition.requires ?? [],
75
- provides: definition.provides ?? [],
76
- requiresValidated: definition.requiresValidated ?? [],
77
- shortCircuits: definition.shortCircuits ?? [],
78
- factory: definition.factory,
79
- });
80
- return Object.freeze(descriptor);
81
- }
@@ -1,4 +0,0 @@
1
- import { type ApplicationCompilationInput } from './graph.js';
2
- import type { CompilationResult } from './ir.js';
3
- export declare function compileApplication(input: ApplicationCompilationInput): CompilationResult;
4
- export declare const buildApplicationGraph: typeof compileApplication;