@oatscenter/trellis 0.100.0-rc.1

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 (264) hide show
  1. package/README.md +59 -0
  2. package/auth/authorization/client_context.d.ts +61 -0
  3. package/auth/authorization/client_context.js +266 -0
  4. package/auth/authorization/nats_registry.d.ts +41 -0
  5. package/auth/authorization/nats_registry.js +283 -0
  6. package/auth/authorization/provider_cache.d.ts +90 -0
  7. package/auth/authorization/provider_cache.js +783 -0
  8. package/auth/authorization/refresh.d.ts +46 -0
  9. package/auth/authorization/refresh.js +246 -0
  10. package/auth/authorization/types.d.ts +207 -0
  11. package/auth/authorization/types.js +60 -0
  12. package/auth/authorization_context.d.ts +11 -0
  13. package/auth/authorization_context.js +10 -0
  14. package/auth/browser/flow_types.d.ts +84 -0
  15. package/auth/browser/flow_types.js +70 -0
  16. package/auth/browser/portal.d.ts +21 -0
  17. package/auth/browser/portal.js +307 -0
  18. package/auth/browser/storage.d.ts +26 -0
  19. package/auth/browser/storage.js +224 -0
  20. package/auth/browser.d.ts +11 -0
  21. package/auth/browser.js +10 -0
  22. package/auth/browser_recovery.d.ts +13 -0
  23. package/auth/browser_recovery.js +38 -0
  24. package/auth/device_activation.d.ts +134 -0
  25. package/auth/device_activation.js +376 -0
  26. package/auth/http_error.d.ts +12 -0
  27. package/auth/http_error.js +32 -0
  28. package/auth/keys.d.ts +5 -0
  29. package/auth/keys.js +63 -0
  30. package/auth/mod.d.ts +16 -0
  31. package/auth/mod.js +16 -0
  32. package/auth/proof.d.ts +31 -0
  33. package/auth/proof.js +95 -0
  34. package/auth/protocol_wasm/trellis_protocol_wasm.d.ts +138 -0
  35. package/auth/protocol_wasm/trellis_protocol_wasm.js +605 -0
  36. package/auth/protocol_wasm/trellis_protocol_wasm_bg.wasm +0 -0
  37. package/auth/protocol_wasm/trellis_protocol_wasm_bytes.d.ts +1 -0
  38. package/auth/protocol_wasm/trellis_protocol_wasm_bytes.js +2 -0
  39. package/auth/protocol_wasm.d.ts +179 -0
  40. package/auth/protocol_wasm.js +133 -0
  41. package/auth/session_auth.d.ts +30 -0
  42. package/auth/session_auth.js +77 -0
  43. package/auth/session_proof.d.ts +53 -0
  44. package/auth/session_proof.js +43 -0
  45. package/auth/time.d.ts +6 -0
  46. package/auth/time.js +7 -0
  47. package/auth/trellis_id.d.ts +1 -0
  48. package/auth/trellis_id.js +5 -0
  49. package/auth/utils.d.ts +10 -0
  50. package/auth/utils.js +69 -0
  51. package/auth.d.ts +1 -0
  52. package/auth.js +1 -0
  53. package/caller.d.ts +111 -0
  54. package/caller.js +85 -0
  55. package/client.d.ts +14 -0
  56. package/client.js +1 -0
  57. package/client_connect.d.ts +143 -0
  58. package/client_connect.js +1097 -0
  59. package/codec.d.ts +13 -0
  60. package/codec.js +192 -0
  61. package/connection.d.ts +107 -0
  62. package/connection.js +396 -0
  63. package/device/activation.d.ts +42 -0
  64. package/device/activation.js +319 -0
  65. package/device.d.ts +80 -0
  66. package/device.js +687 -0
  67. package/env.d.ts +2 -0
  68. package/env.js +10 -0
  69. package/errors/AuthError.d.ts +30 -0
  70. package/errors/AuthError.js +34 -0
  71. package/errors/KVError.d.ts +30 -0
  72. package/errors/KVError.js +36 -0
  73. package/errors/OperationLifecycleError.d.ts +110 -0
  74. package/errors/OperationLifecycleError.js +142 -0
  75. package/errors/RemoteError.d.ts +61 -0
  76. package/errors/RemoteError.js +72 -0
  77. package/errors/SchemaValidationError.d.ts +48 -0
  78. package/errors/SchemaValidationError.js +49 -0
  79. package/errors/StoreError.d.ts +21 -0
  80. package/errors/StoreError.js +31 -0
  81. package/errors/TransferError.d.ts +21 -0
  82. package/errors/TransferError.js +31 -0
  83. package/errors/TransportError.d.ts +29 -0
  84. package/errors/TransportError.js +33 -0
  85. package/errors/TrellisError.d.ts +15 -0
  86. package/errors/TrellisError.js +15 -0
  87. package/errors/ValidationError.d.ts +50 -0
  88. package/errors/ValidationError.js +59 -0
  89. package/errors/index.d.ts +254 -0
  90. package/errors/index.js +238 -0
  91. package/generated.d.ts +4 -0
  92. package/generated.js +3 -0
  93. package/generated_support.d.ts +120 -0
  94. package/generated_support.js +359 -0
  95. package/globals.d.ts +9 -0
  96. package/globals.js +16 -0
  97. package/health_transport.d.ts +18 -0
  98. package/health_transport.js +32 -0
  99. package/helpers.d.ts +11 -0
  100. package/helpers.js +53 -0
  101. package/index.d.ts +2 -0
  102. package/index.js +2 -0
  103. package/internal_sdk/generated/apis/auth/mod.d.ts +805 -0
  104. package/internal_sdk/generated/apis/auth/mod.js +958 -0
  105. package/internal_sdk/generated/apis/core/mod.d.ts +79 -0
  106. package/internal_sdk/generated/apis/core/mod.js +93 -0
  107. package/internal_sdk/generated/apis/events/mod.d.ts +224 -0
  108. package/internal_sdk/generated/apis/events/mod.js +313 -0
  109. package/internal_sdk/generated/apis/health/mod.d.ts +106 -0
  110. package/internal_sdk/generated/apis/health/mod.js +132 -0
  111. package/internal_sdk/generated/apis/index.d.ts +7 -0
  112. package/internal_sdk/generated/apis/index.js +8 -0
  113. package/internal_sdk/generated/apis/jobs/mod.d.ts +176 -0
  114. package/internal_sdk/generated/apis/jobs/mod.js +209 -0
  115. package/internal_sdk/generated/apis/state/mod.d.ts +104 -0
  116. package/internal_sdk/generated/apis/state/mod.js +139 -0
  117. package/internal_sdk/generated/index.d.ts +4 -0
  118. package/internal_sdk/generated/index.js +5 -0
  119. package/internal_sdk/generated/package.json +18 -0
  120. package/internal_sdk/generated/participants/cli/mod.d.ts +402 -0
  121. package/internal_sdk/generated/participants/cli/mod.js +460 -0
  122. package/internal_sdk/generated/participants/cli/types.d.ts +2 -0
  123. package/internal_sdk/generated/participants/cli/types.js +3 -0
  124. package/internal_sdk/generated/participants/console/mod.d.ts +489 -0
  125. package/internal_sdk/generated/participants/console/mod.js +579 -0
  126. package/internal_sdk/generated/participants/console/types.d.ts +2 -0
  127. package/internal_sdk/generated/participants/console/types.js +3 -0
  128. package/internal_sdk/generated/participants/eventsRuntime/mod.d.ts +64 -0
  129. package/internal_sdk/generated/participants/eventsRuntime/mod.js +42 -0
  130. package/internal_sdk/generated/participants/eventsRuntime/types.d.ts +2 -0
  131. package/internal_sdk/generated/participants/eventsRuntime/types.js +3 -0
  132. package/internal_sdk/generated/participants/healthRuntime/mod.d.ts +58 -0
  133. package/internal_sdk/generated/participants/healthRuntime/mod.js +36 -0
  134. package/internal_sdk/generated/participants/healthRuntime/types.d.ts +2 -0
  135. package/internal_sdk/generated/participants/healthRuntime/types.js +3 -0
  136. package/internal_sdk/generated/participants/index.d.ts +8 -0
  137. package/internal_sdk/generated/participants/index.js +9 -0
  138. package/internal_sdk/generated/participants/jobsRuntime/mod.d.ts +64 -0
  139. package/internal_sdk/generated/participants/jobsRuntime/mod.js +42 -0
  140. package/internal_sdk/generated/participants/jobsRuntime/types.d.ts +2 -0
  141. package/internal_sdk/generated/participants/jobsRuntime/types.js +3 -0
  142. package/internal_sdk/generated/participants/platform/mod.d.ts +164 -0
  143. package/internal_sdk/generated/participants/platform/mod.js +149 -0
  144. package/internal_sdk/generated/participants/platform/types.d.ts +7 -0
  145. package/internal_sdk/generated/participants/platform/types.js +5 -0
  146. package/internal_sdk/generated/participants/portal/mod.d.ts +131 -0
  147. package/internal_sdk/generated/participants/portal/mod.js +109 -0
  148. package/internal_sdk/generated/participants/portal/types.d.ts +2 -0
  149. package/internal_sdk/generated/participants/portal/types.js +3 -0
  150. package/internal_sdk/generated/types/_internal/p0.d.ts +13511 -0
  151. package/internal_sdk/generated/types/_internal/p0.js +6105 -0
  152. package/internal_sdk/generated/types/index.d.ts +2951 -0
  153. package/internal_sdk/generated/types/index.js +1477 -0
  154. package/jobs.d.ts +309 -0
  155. package/jobs.js +389 -0
  156. package/kv.d.ts +85 -0
  157. package/kv.js +330 -0
  158. package/operations.d.ts +189 -0
  159. package/operations.js +847 -0
  160. package/package.json +73 -0
  161. package/pagination.d.ts +25 -0
  162. package/pagination.js +117 -0
  163. package/participant.d.ts +6 -0
  164. package/participant.js +6 -0
  165. package/participant_runtime/api.d.ts +131 -0
  166. package/participant_runtime/api.js +42 -0
  167. package/participant_runtime/json.d.ts +16 -0
  168. package/participant_runtime/json.js +193 -0
  169. package/participant_runtime/metadata.d.ts +34 -0
  170. package/participant_runtime/metadata.js +4 -0
  171. package/participant_runtime/participant.d.ts +200 -0
  172. package/participant_runtime/participant.js +330 -0
  173. package/participant_runtime/schemas.d.ts +347 -0
  174. package/participant_runtime/schemas.js +211 -0
  175. package/participant_runtime/surface_names.d.ts +16 -0
  176. package/participant_runtime/surface_names.js +34 -0
  177. package/portable.d.ts +30 -0
  178. package/portable.js +14 -0
  179. package/provider.d.ts +69 -0
  180. package/provider.js +68 -0
  181. package/runtime_transport.d.ts +25 -0
  182. package/runtime_transport.js +48 -0
  183. package/service/mod.d.ts +14 -0
  184. package/service/mod.js +13 -0
  185. package/service/outbox_inbox.d.ts +259 -0
  186. package/service/outbox_inbox.js +908 -0
  187. package/service/runtime/bootstrap.d.ts +56 -0
  188. package/service/runtime/bootstrap.js +226 -0
  189. package/service/runtime/core.d.ts +46 -0
  190. package/service/runtime/core.js +1747 -0
  191. package/service/runtime/health.d.ts +97 -0
  192. package/service/runtime/health.js +153 -0
  193. package/service/runtime/health_schemas.d.ts +23 -0
  194. package/service/runtime/health_schemas.js +20 -0
  195. package/service/runtime/internal_jobs/active-job.d.ts +40 -0
  196. package/service/runtime/internal_jobs/active-job.js +91 -0
  197. package/service/runtime/internal_jobs/bindings.d.ts +40 -0
  198. package/service/runtime/internal_jobs/bindings.js +1 -0
  199. package/service/runtime/internal_jobs/cancellation-registry.d.ts +13 -0
  200. package/service/runtime/internal_jobs/cancellation-registry.js +55 -0
  201. package/service/runtime/internal_jobs/heartbeat.d.ts +33 -0
  202. package/service/runtime/internal_jobs/heartbeat.js +65 -0
  203. package/service/runtime/internal_jobs/job-manager.d.ts +126 -0
  204. package/service/runtime/internal_jobs/job-manager.js +821 -0
  205. package/service/runtime/internal_jobs/key-coordinator.d.ts +280 -0
  206. package/service/runtime/internal_jobs/key-coordinator.js +747 -0
  207. package/service/runtime/internal_jobs/projection.d.ts +3 -0
  208. package/service/runtime/internal_jobs/projection.js +42 -0
  209. package/service/runtime/internal_jobs/runtime-worker.d.ts +126 -0
  210. package/service/runtime/internal_jobs/runtime-worker.js +454 -0
  211. package/service/runtime/internal_jobs/types.d.ts +246 -0
  212. package/service/runtime/internal_jobs/types.js +163 -0
  213. package/service/runtime/logger.d.ts +2 -0
  214. package/service/runtime/logger.js +7 -0
  215. package/service/runtime/runtime.d.ts +16 -0
  216. package/service/runtime/runtime.js +1 -0
  217. package/service/runtime/service.d.ts +372 -0
  218. package/service/runtime/service.js +1896 -0
  219. package/service/runtime/transfer/download.d.ts +27 -0
  220. package/service/runtime/transfer/download.js +1 -0
  221. package/service/runtime/transfer/protocol.d.ts +15 -0
  222. package/service/runtime/transfer/protocol.js +46 -0
  223. package/service/runtime/transfer/queue.d.ts +18 -0
  224. package/service/runtime/transfer/queue.js +136 -0
  225. package/service/runtime/transfer/upload.d.ts +40 -0
  226. package/service/runtime/transfer/upload.js +27 -0
  227. package/service/runtime/transfer.d.ts +62 -0
  228. package/service/runtime/transfer.js +763 -0
  229. package/session.d.ts +862 -0
  230. package/session.js +3407 -0
  231. package/store.d.ts +71 -0
  232. package/store.js +412 -0
  233. package/store_entry.d.ts +20 -0
  234. package/store_entry.js +75 -0
  235. package/tasks.d.ts +10 -0
  236. package/tasks.js +28 -0
  237. package/telemetry/carrier.d.ts +8 -0
  238. package/telemetry/carrier.js +20 -0
  239. package/telemetry/core.d.ts +7 -0
  240. package/telemetry/core.js +14 -0
  241. package/telemetry/env.d.ts +2 -0
  242. package/telemetry/env.js +10 -0
  243. package/telemetry/init.d.ts +2 -0
  244. package/telemetry/init.js +7 -0
  245. package/telemetry/metrics.d.ts +81 -0
  246. package/telemetry/metrics.js +267 -0
  247. package/telemetry/mod.d.ts +13 -0
  248. package/telemetry/mod.js +8 -0
  249. package/telemetry/nats.d.ts +6 -0
  250. package/telemetry/nats.js +6 -0
  251. package/telemetry/result.d.ts +1 -0
  252. package/telemetry/result.js +18 -0
  253. package/telemetry/runtime.d.ts +1 -0
  254. package/telemetry/runtime.js +141 -0
  255. package/telemetry/trace.d.ts +4 -0
  256. package/telemetry/trace.js +26 -0
  257. package/telemetry/trellis.d.ts +1 -0
  258. package/telemetry/trellis.js +1 -0
  259. package/telemetry.d.ts +1 -0
  260. package/telemetry.js +1 -0
  261. package/transfer.d.ts +112 -0
  262. package/transfer.js +525 -0
  263. package/transfer_protocol.d.ts +1 -0
  264. package/transfer_protocol.js +13 -0
package/provider.d.ts ADDED
@@ -0,0 +1,69 @@
1
+ import type { AsyncResult, BaseError } from "@oatscenter/result";
2
+ import { type CallerRuntime } from "./caller.ts";
3
+ import { type GeneratedParticipant } from "./participant_runtime/participant.ts";
4
+ import type { PascalActionName } from "./participant_runtime/surface_names.ts";
5
+ import type { EventListenerContext } from "./session.ts";
6
+ import type { InferSchemaType, RuntimeApi } from "./participant_runtime/api.ts";
7
+ import type { ParticipantJobsMetadata, ParticipantKvMetadata } from "./participant_runtime/metadata.ts";
8
+ import type { FeedHandler, GeneratedServiceParticipant, OperationHandler, RpcHandler } from "./service/runtime/service.ts";
9
+ export declare const PROVIDER_CALLER: unique symbol;
10
+ export type ProviderCaller = object;
11
+ type ProviderBase<TService> = TService extends {
12
+ readonly health: infer THealth;
13
+ readonly connection: infer TConnection;
14
+ readonly name: infer TName;
15
+ readonly createSqlOutbox: infer TCreateSqlOutbox;
16
+ readonly createTransfer: infer TCreateTransfer;
17
+ } ? {
18
+ readonly health: THealth;
19
+ readonly connection: TConnection;
20
+ readonly name: TName;
21
+ readonly createSqlOutbox: TCreateSqlOutbox;
22
+ readonly createTransfer: TCreateTransfer;
23
+ wait(): Promise<void>;
24
+ stop(): Promise<void>;
25
+ } : {};
26
+ type ProviderResources<TService> = TService extends {
27
+ readonly kv: infer TKv;
28
+ readonly store: infer TStore;
29
+ readonly jobs: infer TJobs;
30
+ } ? {
31
+ readonly kv: TKv;
32
+ readonly store: TStore;
33
+ readonly jobs: TJobs;
34
+ } : {};
35
+ type ServiceContract<TContract extends GeneratedParticipant> = Extract<TContract, GeneratedServiceParticipant<RuntimeApi, RuntimeApi | undefined, ParticipantJobsMetadata, ParticipantKvMetadata>>;
36
+ type OwnedApi<TContract extends GeneratedParticipant> = TContract extends {
37
+ readonly __runtimeTypes?: {
38
+ readonly ownedApi: infer TApi;
39
+ };
40
+ } ? Extract<TApi, RuntimeApi> : never;
41
+ type ProviderRegistrations<TContract extends GeneratedParticipant> = {
42
+ readonly [K in keyof OwnedApi<TContract>["rpc"] & string as `handle${PascalActionName<K>}`]: (handler: RpcHandler<ServiceContract<TContract>, K>) => unknown;
43
+ } & {
44
+ readonly [K in keyof OwnedApi<TContract>["operations"] & string as `handle${PascalActionName<K>}`]: (handler: OperationHandler<ServiceContract<TContract>, K>) => unknown;
45
+ } & {
46
+ readonly [K in keyof NonNullable<OwnedApi<TContract>["feeds"]> & string as `handle${PascalActionName<K>}`]: (handler: FeedHandler<ServiceContract<TContract>, K>) => unknown;
47
+ } & {
48
+ readonly [K in keyof OwnedApi<TContract>["events"] & string as `on${PascalActionName<K>}`]: (handler: (args: {
49
+ event: InferSchemaType<OwnedApi<TContract>["events"][K]["event"]>;
50
+ context: EventListenerContext;
51
+ client: ProviderCallerSurface<TContract>;
52
+ }) => unknown | Promise<unknown>, subjectData?: Record<string, unknown>, options?: unknown) => AsyncResult<void, BaseError>;
53
+ } & {
54
+ readonly [K in keyof OwnedApi<TContract>["events"] & string as `publish${PascalActionName<K>}`]: (event: InferSchemaType<OwnedApi<TContract>["events"][K]["event"]>) => AsyncResult<void, BaseError>;
55
+ };
56
+ type ProviderOwnedPublish<TContract extends GeneratedParticipant> = {
57
+ readonly [K in keyof OwnedApi<TContract>["events"] & string as `publish${PascalActionName<K>}`]: (event: InferSchemaType<OwnedApi<TContract>["events"][K]["event"]>) => AsyncResult<void, BaseError>;
58
+ };
59
+ type ProviderCallerSurface<TContract extends GeneratedParticipant> = Omit<CallerRuntime<TContract>, "connection" | "kv" | "state" | "store" | "wait" | Extract<keyof CallerRuntime<TContract>, `on${string}` | `publish${string}`>>;
60
+ /** Caller and bound-resource surface available inside provider handlers. */
61
+ export type ProviderHandlerClient<TContract extends GeneratedParticipant, TService> = ProviderCallerSurface<TContract> & ProviderOwnedPublish<TContract> & ProviderResources<TService> & (ProviderBase<TService> extends infer TBase ? TBase extends {
62
+ connection: unknown;
63
+ name: unknown;
64
+ } ? Pick<TBase, "connection" | "name"> : {} : {});
65
+ /** Connected provider facade for a generated service participant. */
66
+ export type ProviderRuntime<TContract extends GeneratedParticipant, TService> = ProviderBase<TService> & ProviderResources<TService> & ProviderCallerSurface<TContract> & ProviderRegistrations<TContract>;
67
+ /** Projects a connected service into its flat provider and caller vocabulary. */
68
+ export declare function createProviderRuntime<TContract extends GeneratedParticipant, TService extends object>(connectedService: TService, contract: TContract): ProviderRuntime<TContract, TService>;
69
+ export {};
package/provider.js ADDED
@@ -0,0 +1,68 @@
1
+ import { createCallerRuntime } from "./caller.js";
2
+ import { getParticipantRuntime, } from "./participant_runtime/participant.js";
3
+ import { lowerCamelSurfaceName, pascalSurfaceName, } from "./participant_runtime/surface_names.js";
4
+ export const PROVIDER_CALLER = Symbol("trellis.provider.caller");
5
+ function surfacePath(name) {
6
+ const [head, ...tail] = name.split(".");
7
+ return [
8
+ lowerCamelSurfaceName(head),
9
+ lowerCamelSurfaceName(tail.length === 0 ? name : tail.join(".")),
10
+ ];
11
+ }
12
+ /** Projects a connected service into its flat provider and caller vocabulary. */
13
+ export function createProviderRuntime(connectedService, contract) {
14
+ const service = connectedService;
15
+ const provider = {
16
+ kv: service.kv,
17
+ store: service.store,
18
+ health: service.health,
19
+ connection: service.connection,
20
+ name: service.name,
21
+ createSqlOutbox: service.createSqlOutbox.bind(service),
22
+ createTransfer: service.createTransfer.bind(service),
23
+ publishPrepared: service.publishPrepared.bind(service),
24
+ wait: service.wait.bind(service),
25
+ stop: service.stop.bind(service),
26
+ };
27
+ provider.jobs = Object.fromEntries(Object.entries(service.jobs).map(([name, queue]) => [name, {
28
+ ...queue,
29
+ handle: (handler, options) => queue.handle((args) => handler({ ...args, client: provider }), options),
30
+ }]));
31
+ const caller = createCallerRuntime(service[PROVIDER_CALLER], contract);
32
+ for (const action of getParticipantRuntime(contract).actions) {
33
+ const connected = caller[action.connectedName];
34
+ if (action.descriptor.kind === "event" && action.direction === "subscribe") {
35
+ provider[action.connectedName] = (handler, subjectData, options) => service[PROVIDER_CALLER].listenEvent(action.name, subjectData ?? {}, (message, context) => handler({ event: message, context, client: provider }), options);
36
+ }
37
+ else {
38
+ provider[action.connectedName] = connected;
39
+ }
40
+ }
41
+ for (const name of Object.keys(getParticipantRuntime(contract).ownedApi.rpc)) {
42
+ const [group, leaf] = surfacePath(name);
43
+ const register = service.handle.rpc[group][leaf];
44
+ provider[`handle${pascalSurfaceName(name)}`] = (handler) => register((args) => handler({ ...args, client: provider }));
45
+ }
46
+ for (const name of Object.keys(getParticipantRuntime(contract).ownedApi.operations)) {
47
+ const [group, leaf] = surfacePath(name);
48
+ const register = service.handle.operation[group][leaf];
49
+ const expose = (handler) => register((args) => handler({ ...args, client: provider }));
50
+ provider[`handle${pascalSurfaceName(name)}`] = Object.assign(expose, {
51
+ ...(register.accept ? { accept: register.accept.bind(register) } : {}),
52
+ ...(register.control ? { control: register.control.bind(register) } : {}),
53
+ });
54
+ }
55
+ for (const name of Object.keys(getParticipantRuntime(contract).ownedApi.feeds ?? {})) {
56
+ const [group, leaf] = surfacePath(name);
57
+ const register = service.handle.feed[group][leaf];
58
+ provider[`handle${pascalSurfaceName(name)}`] = (handler) => register((args) => handler(args));
59
+ }
60
+ for (const name of Object.keys(getParticipantRuntime(contract).ownedApi.events)) {
61
+ provider[`on${pascalSurfaceName(name)}`] = (handler, subjectData, options) => service[PROVIDER_CALLER].listenEvent(name, subjectData ?? {}, (message, context) => handler({ event: message, context, client: provider }), options);
62
+ const publish = Object.assign((event) => service[PROVIDER_CALLER].publish(name, event), {
63
+ prepare: (event) => service[PROVIDER_CALLER].prepare(name, event),
64
+ });
65
+ provider[`publish${pascalSurfaceName(name)}`] = publish;
66
+ }
67
+ return provider;
68
+ }
@@ -0,0 +1,25 @@
1
+ import type { Authenticator, NatsConnection } from "@nats-io/nats-core";
2
+ type RuntimeTransportEndpoints = {
3
+ natsServers: string[];
4
+ };
5
+ type RuntimeTransports = {
6
+ native?: RuntimeTransportEndpoints;
7
+ websocket?: RuntimeTransportEndpoints;
8
+ };
9
+ export declare const DEFAULT_RUNTIME_MAX_RECONNECT_ATTEMPTS = -1;
10
+ export declare const DEFAULT_SERVICE_RUNTIME_WAIT_ON_FIRST_CONNECT = true;
11
+ export type RuntimeTransportConnectOptions = {
12
+ servers: string | string[];
13
+ token?: string;
14
+ authenticator?: Authenticator | Authenticator[];
15
+ inboxPrefix?: string;
16
+ maxReconnectAttempts?: number;
17
+ waitOnFirstConnect?: boolean;
18
+ } & Record<string, unknown>;
19
+ export type RuntimeTransport = {
20
+ connect(options: RuntimeTransportConnectOptions): Promise<NatsConnection>;
21
+ };
22
+ export declare function selectRuntimeTransportServers(transports: RuntimeTransports): string[];
23
+ /** Loads WebSocket transport in browsers and native Node transport in Node/Deno. */
24
+ export declare function loadDefaultRuntimeTransport(): Promise<RuntimeTransport>;
25
+ export {};
@@ -0,0 +1,48 @@
1
+ import { wsconnect } from "@nats-io/nats-core";
2
+ export const DEFAULT_RUNTIME_MAX_RECONNECT_ATTEMPTS = -1;
3
+ export const DEFAULT_SERVICE_RUNTIME_WAIT_ON_FIRST_CONNECT = true;
4
+ export function selectRuntimeTransportServers(transports) {
5
+ if (isBrowserRuntime()) {
6
+ if (transports.websocket?.natsServers?.length) {
7
+ return transports.websocket.natsServers;
8
+ }
9
+ if (transports.native?.natsServers?.length) {
10
+ return transports.native.natsServers;
11
+ }
12
+ }
13
+ else {
14
+ if (transports.native?.natsServers?.length) {
15
+ return transports.native.natsServers;
16
+ }
17
+ if (transports.websocket?.natsServers?.length) {
18
+ return transports.websocket.natsServers;
19
+ }
20
+ }
21
+ throw new Error("No supported NATS transport endpoints available");
22
+ }
23
+ function isBrowserRuntime() {
24
+ const browserGlobal = globalThis;
25
+ return typeof browserGlobal.window !== "undefined" &&
26
+ typeof browserGlobal.document !== "undefined";
27
+ }
28
+ function usesWebSocketTransport(servers) {
29
+ const values = Array.isArray(servers) ? servers : [servers];
30
+ return values.some((server) => server.startsWith("ws://") || server.startsWith("wss://"));
31
+ }
32
+ /** Loads WebSocket transport in browsers and native Node transport in Node/Deno. */
33
+ export async function loadDefaultRuntimeTransport() {
34
+ if (isBrowserRuntime()) {
35
+ return {
36
+ connect: wsconnect,
37
+ };
38
+ }
39
+ return {
40
+ connect: async (options) => {
41
+ if (usesWebSocketTransport(options.servers)) {
42
+ return await wsconnect(options);
43
+ }
44
+ const { connect } = await import("@nats-io/transport-node");
45
+ return await connect(options);
46
+ },
47
+ };
48
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Trellis service authoring entry point.
3
+ *
4
+ * This subpath exposes the service wrapper and service-side helpers without the
5
+ * internal service runtime implementation.
6
+ *
7
+ * @module
8
+ */
9
+ export { type HealthCheckResult, runAllServiceHealthChecks, runServiceHealthCheck, type ServiceHealth, type ServiceHealthCheck, type ServiceHealthCheckFn, type ServiceHealthInfo, type ServiceHealthInfoFn, } from "./runtime/health.ts";
10
+ export { HealthCheckResultSchema, HealthInfoSchema, } from "./runtime/health_schemas.ts";
11
+ export { type ConnectedTrellisService, type FeedHandler, type GeneratedServiceParticipant, type HealthCheckHandler, type HealthInfoHandler, type JobHandler, type OperationHandler, type OperationRegistration, type RpcHandler, type ServiceEventHandler, type SqlOutbox, type SqlOutboxEventEnqueueFacade, type SqlOutboxJobEnqueueFacade, type SqlOutboxJobSubmission, type SqlOutboxTransactionContext, type SqlOutboxTransactionRunner, TrellisService, type TrellisServiceConnectOpts, type TrellisServiceConnectTelemetryOpts, type TrellisServiceSqlOutboxCommonOptions, type TrellisServiceSqlOutboxExecutorOptions, type TrellisServiceSqlOutboxOptions, } from "./runtime/service.ts";
12
+ export { createPostgresOutboxSchema, createSqliteOutboxSchema, createSqlOutboxAdapter, defaultSqlOutboxTables, dispatchOutbox, getSqlOutboxMigrations, type InboxRepository, type KvOutboxRecord, KvOutboxRecordSchema, MemoryInboxRepository, MemoryOutboxRepository, NatsKvInboxRepository, NatsKvOutboxRepository, OutboxDispatcher, type OutboxDispatcherOptions, type OutboxDispatchResult, type OutboxDispatchRuntime, type OutboxJobDispatchOutcome, type OutboxKvStore, type OutboxMessage, type OutboxMessageState, outboxMessageToPreparedEvent, type OutboxRecordKind, type OutboxRepository, type PreparedOutboxRecord, preparedTrellisEventToOutboxRecord, type SqlDialect, type SqlExecutor, SqlInboxRepository, type SqlOutboxAdapter, type SqlOutboxMigration, type SqlOutboxMigrationOptions, SqlOutboxRepository, type SqlOutboxTables, type SqlRow, } from "./outbox_inbox.ts";
13
+ export { ActiveJob, decodeJobUpdateEnvelope, JobLogEntrySchema, JobProgressSchema, JobQueue, JobRef, JobWorkerHostAdapter, RetryJobError, } from "../jobs.ts";
14
+ export type { Job, JobFilter, JobHandlerOptions, JobIdentity, JobLogEntry, JobProgress, JobsFacade, JobsFacadeOf, JobSnapshot, JobState, JobTypeMetadata, JobUpdateEnvelope, JobUpdatesOptions, JobUpdateSubscription, JobWorkerHost, RetryJobErrorData, ServiceInfo, TerminalJob, WorkerInfo, } from "../jobs.ts";
package/service/mod.js ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Trellis service authoring entry point.
3
+ *
4
+ * This subpath exposes the service wrapper and service-side helpers without the
5
+ * internal service runtime implementation.
6
+ *
7
+ * @module
8
+ */
9
+ export { runAllServiceHealthChecks, runServiceHealthCheck, } from "./runtime/health.js";
10
+ export { HealthCheckResultSchema, HealthInfoSchema, } from "./runtime/health_schemas.js";
11
+ export { TrellisService, } from "./runtime/service.js";
12
+ export { createPostgresOutboxSchema, createSqliteOutboxSchema, createSqlOutboxAdapter, defaultSqlOutboxTables, dispatchOutbox, getSqlOutboxMigrations, KvOutboxRecordSchema, MemoryInboxRepository, MemoryOutboxRepository, NatsKvInboxRepository, NatsKvOutboxRepository, OutboxDispatcher, outboxMessageToPreparedEvent, preparedTrellisEventToOutboxRecord, SqlInboxRepository, SqlOutboxRepository, } from "./outbox_inbox.js";
13
+ export { ActiveJob, decodeJobUpdateEnvelope, JobLogEntrySchema, JobProgressSchema, JobQueue, JobRef, JobWorkerHostAdapter, RetryJobError, } from "../jobs.js";
@@ -0,0 +1,259 @@
1
+ import { type AsyncResult, type BaseError, type UnexpectedError } from "@oatscenter/result";
2
+ import { type StaticDecode, Type } from "typebox";
3
+ import type { TypedKV } from "../kv.ts";
4
+ import type { PreparedTrellisEvent } from "../session.ts";
5
+ export type OutboxMessageState = "pending" | "claimed" | "dispatched" | "failed";
6
+ export type OutboxRecordKind = "event.publish" | "job.create" | "job.submit";
7
+ export type PreparedOutboxRecord = {
8
+ readonly id: string;
9
+ readonly kind: OutboxRecordKind;
10
+ readonly name: string;
11
+ readonly subject: string;
12
+ readonly payload: string;
13
+ readonly headers: Readonly<Record<string, string>>;
14
+ };
15
+ export type OutboxMessage = {
16
+ id: string;
17
+ kind: OutboxRecordKind;
18
+ name: string;
19
+ subject: string;
20
+ payload: string;
21
+ headers: Record<string, string>;
22
+ state: OutboxMessageState;
23
+ attempts: number;
24
+ createdAt: string;
25
+ updatedAt: string;
26
+ nextAttemptAt?: string;
27
+ lastError?: string;
28
+ outcome?: unknown;
29
+ };
30
+ /** Raised when an outbox ID is reused for different immutable content. */
31
+ export declare class OutboxDuplicateIdentityError extends Error {
32
+ readonly id: string;
33
+ constructor(id: string);
34
+ }
35
+ /** Raised when storage reports a duplicate but the winning row cannot be read. */
36
+ export declare class OutboxStorageConflictError extends Error {
37
+ readonly id: string;
38
+ constructor(id: string);
39
+ }
40
+ export type OutboxDispatchResult = {
41
+ dispatched: number;
42
+ failed: number;
43
+ };
44
+ /** Queue-admission result persisted after a SQL-outboxed job is dispatched. */
45
+ export type OutboxJobDispatchOutcome = {
46
+ readonly kind: string;
47
+ readonly [key: string]: unknown;
48
+ };
49
+ /** Options for {@link OutboxDispatcher}. */
50
+ export type OutboxDispatcherOptions = {
51
+ /** Maximum number of messages claimed by each `dispatchOutbox` batch. */
52
+ limit?: number;
53
+ /** Delay before failed messages become eligible; values below 1ms become 1ms. */
54
+ retryDelayMs?: number;
55
+ /** Delay used to debounce `notify()` calls before starting a drain. */
56
+ debounceMs?: number;
57
+ /** Optional low-frequency wakeup for missed signals or process restarts. */
58
+ idleRetryMs?: number;
59
+ /** Receives repository or publish errors raised by background dispatch. */
60
+ onError?: (error: unknown) => void;
61
+ };
62
+ export type OutboxDispatchRuntime = {
63
+ /** Dispatches an event-publish outbox record. Returns Void on success, err on transient failure. */
64
+ publishPreparedEvent(event: PreparedTrellisEvent): AsyncResult<void, UnexpectedError>;
65
+ /** Dispatches a job create/submit outbox record and returns its queue-admission outcome. */
66
+ dispatchJobSubmission?(message: OutboxMessage): AsyncResult<OutboxJobDispatchOutcome, BaseError>;
67
+ };
68
+ export type OutboxRepository = {
69
+ enqueue(record: PreparedOutboxRecord): Promise<OutboxMessage>;
70
+ get(id: string): Promise<OutboxMessage | undefined>;
71
+ /** Claim due work for 30 seconds; the returned attempt fences completion. */
72
+ claimDue(limit: number, now: Date): Promise<OutboxMessage[]>;
73
+ /** Complete the returned claim; false means its ownership was superseded. */
74
+ markDispatched(claim: OutboxMessage, now: Date, outcome?: unknown): Promise<boolean>;
75
+ /** Retry the returned claim; false means its ownership was superseded. */
76
+ markFailed(claim: OutboxMessage, failure: {
77
+ error: string;
78
+ nextAttemptAt: Date;
79
+ now: Date;
80
+ }): Promise<boolean>;
81
+ };
82
+ export type InboxRepository = {
83
+ /** Insert a dedupe marker; true only when this call inserted it. */
84
+ record(messageId: string, now?: Date): Promise<boolean>;
85
+ };
86
+ /** SQL dialects supported by Trellis SQL outbox helpers. */
87
+ export type SqlDialect = "sqlite" | "postgres";
88
+ /** Table names used by Trellis SQL outbox and inbox helper tables. */
89
+ export type SqlOutboxTables = {
90
+ outbox: string;
91
+ inbox: string;
92
+ };
93
+ /** Minimal SQL execution surface used by Trellis SQL outbox repositories. */
94
+ export type SqlExecutor = {
95
+ query(sql: string, params: readonly unknown[]): Promise<readonly SqlRow[]>;
96
+ execute(sql: string, params: readonly unknown[]): Promise<void>;
97
+ };
98
+ /** Row shape returned by a {@link SqlExecutor}. */
99
+ export type SqlRow = Record<string, unknown>;
100
+ /** SQL outbox adapter bundle over caller-owned SQL execution. */
101
+ export type SqlOutboxAdapter = {
102
+ outbox: SqlOutboxRepository;
103
+ inbox: SqlInboxRepository;
104
+ ddl: readonly string[];
105
+ };
106
+ /** Versioned Trellis-owned SQL outbox/inbox migration artifact. */
107
+ export type SqlOutboxMigration = {
108
+ /** Stable migration identifier for the dialect and schema version. */
109
+ readonly id: string;
110
+ /** Monotonic Trellis helper-table schema version. */
111
+ readonly version: number;
112
+ /** SQL dialect targeted by this migration artifact. */
113
+ readonly dialect: SqlDialect;
114
+ /** SQL statements that apply this migration. */
115
+ readonly up: readonly string[];
116
+ /** SQL statements that revert this migration when supported by the runner. */
117
+ readonly down?: readonly string[];
118
+ /** Deterministic checksum over the canonical migration SQL. */
119
+ readonly checksum: string;
120
+ };
121
+ /** Options for generating Trellis SQL outbox/inbox migration artifacts. */
122
+ export type SqlOutboxMigrationOptions = {
123
+ /** SQL dialect targeted by the generated migration artifacts. */
124
+ readonly dialect: SqlDialect;
125
+ /** Optional helper-table names; omitted names use Trellis defaults. */
126
+ readonly tables?: Partial<SqlOutboxTables>;
127
+ };
128
+ export type OutboxKvStore = Pick<TypedKV<KvOutboxRecord>, "create" | "getEntry" | "replace" | "keys">;
129
+ /** Default Trellis helper-table names for SQL outbox and inbox storage. */
130
+ export declare const defaultSqlOutboxTables: SqlOutboxTables;
131
+ /**
132
+ * Creates SQL outbox/inbox repositories plus current helper-table DDL.
133
+ *
134
+ * Use {@link getSqlOutboxMigrations} when services need versioned Trellis-owned
135
+ * migration artifacts for their normal database migration tooling.
136
+ */
137
+ export declare function createSqlOutboxAdapter(executor: SqlExecutor, dialect: SqlDialect, tables?: SqlOutboxTables): SqlOutboxAdapter;
138
+ /**
139
+ * Returns Trellis-owned SQL outbox/inbox migration artifacts for a dialect.
140
+ *
141
+ * Trellis generates the helper-table SQL, but services remain responsible for
142
+ * running these artifacts through their normal database migration tooling.
143
+ */
144
+ export declare function getSqlOutboxMigrations(options: SqlOutboxMigrationOptions): readonly SqlOutboxMigration[];
145
+ /** Returns SQLite DDL for Trellis outbox and inbox tables. */
146
+ export declare function createSqliteOutboxSchema(tables?: SqlOutboxTables): readonly string[];
147
+ /** Returns Postgres DDL for Trellis outbox and inbox tables. */
148
+ export declare function createPostgresOutboxSchema(tables?: SqlOutboxTables): readonly string[];
149
+ /** In-memory outbox repository intended for tests and local process adapters. */
150
+ export declare class MemoryOutboxRepository implements OutboxRepository {
151
+ #private;
152
+ enqueue(record: PreparedOutboxRecord): Promise<OutboxMessage>;
153
+ get(id: string): Promise<OutboxMessage | undefined>;
154
+ claimDue(limit: number, now: Date): Promise<OutboxMessage[]>;
155
+ markDispatched(claim: OutboxMessage, now: Date, outcome?: unknown): Promise<boolean>;
156
+ markFailed(claim: OutboxMessage, failure: {
157
+ error: string;
158
+ nextAttemptAt: Date;
159
+ now: Date;
160
+ }): Promise<boolean>;
161
+ snapshot(): readonly OutboxMessage[];
162
+ }
163
+ /** In-memory inbox repository intended for duplicate-suppression tests. */
164
+ export declare class MemoryInboxRepository implements InboxRepository {
165
+ #private;
166
+ record(messageId: string): Promise<boolean>;
167
+ }
168
+ /** SQL-backed outbox repository over a caller-owned executor. */
169
+ export declare class SqlOutboxRepository implements OutboxRepository {
170
+ readonly executor: SqlExecutor;
171
+ readonly dialect: SqlDialect;
172
+ readonly tables: SqlOutboxTables;
173
+ constructor(executor: SqlExecutor, dialect: SqlDialect, tables?: SqlOutboxTables);
174
+ enqueue(record: PreparedOutboxRecord): Promise<OutboxMessage>;
175
+ get(id: string): Promise<OutboxMessage | undefined>;
176
+ claimDue(limit: number, now: Date): Promise<OutboxMessage[]>;
177
+ markDispatched(claim: OutboxMessage, now: Date, outcome?: unknown): Promise<boolean>;
178
+ markFailed(claim: OutboxMessage, failure: {
179
+ error: string;
180
+ nextAttemptAt: Date;
181
+ now: Date;
182
+ }): Promise<boolean>;
183
+ }
184
+ /** SQL-backed inbox repository over a caller-owned executor. */
185
+ export declare class SqlInboxRepository implements InboxRepository {
186
+ readonly executor: SqlExecutor;
187
+ readonly dialect: SqlDialect;
188
+ readonly tables: SqlOutboxTables;
189
+ constructor(executor: SqlExecutor, dialect: SqlDialect, tables?: SqlOutboxTables);
190
+ record(messageId: string, now?: Date): Promise<boolean>;
191
+ }
192
+ declare const KvInboxRecordSchema: Type.TObject<{
193
+ messageId: Type.TString;
194
+ receivedAt: Type.TString;
195
+ }>;
196
+ type KvInboxRecord = StaticDecode<typeof KvInboxRecordSchema>;
197
+ export declare const KvOutboxRecordSchema: Type.TObject<{
198
+ id: Type.TString;
199
+ kind: Type.TString;
200
+ name: Type.TString;
201
+ subject: Type.TString;
202
+ payload: Type.TString;
203
+ headers: Type.TRecord<"^.*$", Type.TString>;
204
+ state: Type.TUnion<[Type.TLiteral<"pending">, Type.TLiteral<"dispatched">, Type.TLiteral<"failed">, Type.TLiteral<"claimed">]>;
205
+ attempts: Type.TNumber;
206
+ createdAt: Type.TString;
207
+ updatedAt: Type.TString;
208
+ nextAttemptAt: Type.TOptional<Type.TString>;
209
+ lastError: Type.TOptional<Type.TString>;
210
+ outcome: Type.TOptional<Type.TString>;
211
+ }>;
212
+ export type KvOutboxRecord = StaticDecode<typeof KvOutboxRecordSchema>;
213
+ /** Durable NATS KV outbox repository for services without SQL state. */
214
+ export declare class NatsKvOutboxRepository implements OutboxRepository {
215
+ readonly kv: OutboxKvStore;
216
+ constructor(kv: OutboxKvStore);
217
+ enqueue(rec: PreparedOutboxRecord): Promise<OutboxMessage>;
218
+ get(id: string): Promise<OutboxMessage | undefined>;
219
+ claimDue(limit: number, now: Date): Promise<OutboxMessage[]>;
220
+ markDispatched(claim: OutboxMessage, now: Date, outcome?: unknown): Promise<boolean>;
221
+ markFailed(claim: OutboxMessage, failure: {
222
+ error: string;
223
+ nextAttemptAt: Date;
224
+ now: Date;
225
+ }): Promise<boolean>;
226
+ }
227
+ /** Durable NATS KV inbox repository for event-id duplicate suppression. */
228
+ export declare class NatsKvInboxRepository implements InboxRepository {
229
+ readonly kv: TypedKV<KvInboxRecord>;
230
+ constructor(kv: TypedKV<KvInboxRecord>);
231
+ record(messageId: string, now?: Date): Promise<boolean>;
232
+ }
233
+ /**
234
+ * Coalesces outbox wakeups and drains due messages through `dispatchOutbox`.
235
+ *
236
+ * The dispatcher is process-local coordination only. Callers should invoke
237
+ * `notify()` after committing outbox rows so dispatch does not observe rolled
238
+ * back work.
239
+ */
240
+ export declare class OutboxDispatcher {
241
+ #private;
242
+ /** Creates a dispatcher over an existing outbox repository and runtime. */
243
+ constructor(repository: OutboxRepository, runtime: OutboxDispatchRuntime, options?: OutboxDispatcherOptions);
244
+ /** Signals that outbox work may be available and schedules a drain soon. */
245
+ notify(): void;
246
+ /** Cancels pending wakeups and prevents future dispatch work. */
247
+ stop(): void;
248
+ }
249
+ /** Dispatches due outbox messages through a dispatch runtime. */
250
+ export declare function dispatchOutbox(repository: OutboxRepository, runtime: OutboxDispatchRuntime, options?: {
251
+ limit?: number;
252
+ now?: Date;
253
+ retryDelayMs?: number;
254
+ }): Promise<OutboxDispatchResult>;
255
+ /** Rehydrates a persisted outbox event row into a prepared event. */
256
+ export declare function outboxMessageToPreparedEvent(message: OutboxMessage): PreparedTrellisEvent;
257
+ /** Adapts a prepared Trellis event into a generic outbox record. */
258
+ export declare function preparedTrellisEventToOutboxRecord(event: PreparedTrellisEvent): PreparedOutboxRecord;
259
+ export {};