@ms-cloudpack/api-server 0.64.1 → 0.64.3

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.
@@ -1,14 +1,45 @@
1
1
  import { type TRPCMutationProcedure, type TRPCQueryProcedure, type TRPCSubscriptionProcedure } from '@trpc/server';
2
2
  import type { Context } from '../types/Context.js';
3
- import type { z } from 'zod/v4-mini';
3
+ import { z } from 'zod/v4-mini';
4
4
  import type { ApiParams } from '../types/ApiParams.js';
5
5
  import type { Session } from '@ms-cloudpack/common-types';
6
6
  export type CreateContext = () => Promise<Context>;
7
+ /**
8
+ * tRPC backend (the initialization functions should only be called once).
9
+ * Exported for testing.
10
+ */
11
+ export declare const trpc: import("@trpc/server").TRPCRootObject<Context, object, {
12
+ errorFormatter(opts: {
13
+ error: import("@trpc/server").TRPCError;
14
+ type: import("@trpc/server").ProcedureType | "unknown";
15
+ path: string | undefined;
16
+ input: unknown;
17
+ ctx: Context | undefined;
18
+ shape: import("@trpc/server").TRPCDefaultErrorShape;
19
+ }): {
20
+ message: string;
21
+ code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
22
+ data: import("@trpc/server").TRPCDefaultErrorData;
23
+ };
24
+ }, {
25
+ ctx: Context;
26
+ meta: object;
27
+ errorShape: {
28
+ message: string;
29
+ code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
30
+ data: import("@trpc/server").TRPCDefaultErrorData;
31
+ };
32
+ transformer: false;
33
+ }>;
7
34
  /** Reusable TRPC router helper. */
8
35
  export declare const createRouter: import("@trpc/server").TRPCRouterBuilder<{
9
36
  ctx: Context;
10
37
  meta: object;
11
- errorShape: import("@trpc/server").TRPCDefaultErrorShape;
38
+ errorShape: {
39
+ message: string;
40
+ code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
41
+ data: import("@trpc/server").TRPCDefaultErrorData;
42
+ };
12
43
  transformer: false;
13
44
  }>;
14
45
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/trpc/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC/B,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAE1D,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;AAKnD,mCAAmC;AACnC,eAAO,MAAM,YAAY;;;;;EAAW,CAAC;AAErC;;;;GAIG;AACH,KAAK,SAAS,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,OAAO,EAAE,MAAM,OAAO,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAExH;;;GAGG;AACH,KAAK,YAAY,CAAC,MAAM,EAAE,OAAO,IAAI;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC;AAErF;;;;;GAKG;AAKH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAC/C,SAAS,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,GACtC,qBAAqB,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAQtD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,EAC5C,SAAS,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,GACtC,kBAAkB,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAQnD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,EACnD,SAAS,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,GACtC,yBAAyB,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAQ1D"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/trpc/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC/B,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,CAAC,EAAE,MAAM,aAAa,CAAC;AAChC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAI1D,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;AAEnD;;;GAGG;AACH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;EAef,CAAC;AAEH,mCAAmC;AACnC,eAAO,MAAM,YAAY;;;;;;;;;EAAc,CAAC;AAExC;;;;GAIG;AACH,KAAK,SAAS,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,OAAO,EAAE,MAAM,OAAO,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAExH;;;GAGG;AACH,KAAK,YAAY,CAAC,MAAM,EAAE,OAAO,IAAI;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC;AAErF;;;;;GAKG;AAKH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAC/C,SAAS,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,GACtC,qBAAqB,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAQtD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,EAC5C,SAAS,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,GACtC,kBAAkB,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAQnD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,EACnD,SAAS,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,GACtC,yBAAyB,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAQ1D"}
@@ -1,8 +1,27 @@
1
1
  import { initTRPC, } from '@trpc/server';
2
- // Initialization of tRPC backend. Should be done only once per backend!
3
- const t = initTRPC.context().create();
2
+ import { z } from 'zod/v4-mini';
3
+ /**
4
+ * tRPC backend (the initialization functions should only be called once).
5
+ * Exported for testing.
6
+ */
7
+ export const trpc = initTRPC.context().create({
8
+ errorFormatter(opts) {
9
+ const { shape, error } = opts;
10
+ return {
11
+ ...shape,
12
+ message:
13
+ // For zod validation errors, make them more readable (can't use instanceof here because
14
+ // ZodError is missing from the v4-mini exports; the actual class name is $ZodError).
15
+ // This is tested in the `getData` and `onDataChanged` tests.
16
+ error.code === 'BAD_REQUEST' && error.cause?.name.endsWith('ZodError')
17
+ ? z.prettifyError(error.cause)
18
+ : error.message,
19
+ };
20
+ // };
21
+ },
22
+ });
4
23
  /** Reusable TRPC router helper. */
5
- export const createRouter = t.router;
24
+ export const createRouter = trpc.router;
6
25
  /**
7
26
  * Mutation procedure helper for tRPC.
8
27
  *
@@ -14,7 +33,7 @@ export const createRouter = t.router;
14
33
  // loses the original types during declaration emit, and instead emits copies with all the same
15
34
  // properties but no docs.
16
35
  export function mutationProcedure(procedure, input, output) {
17
- return t.procedure
36
+ return trpc.procedure
18
37
  .input(input)
19
38
  .output(output)
20
39
  // eslint-disable-next-line
@@ -27,7 +46,7 @@ export function mutationProcedure(procedure, input, output) {
27
46
  * and any docs are preserved in the procedures exposed on the client.
28
47
  */
29
48
  export function queryProcedure(procedure, input, output) {
30
- return t.procedure
49
+ return trpc.procedure
31
50
  .input(input)
32
51
  .output(output)
33
52
  // eslint-disable-next-line
@@ -40,7 +59,7 @@ export function queryProcedure(procedure, input, output) {
40
59
  * and any docs are preserved in the procedures exposed on the client.
41
60
  */
42
61
  export function subscriptionProcedure(procedure, input, output) {
43
- return t.procedure
62
+ return trpc.procedure
44
63
  .input(input)
45
64
  .output(output)
46
65
  // eslint-disable-next-line
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/trpc/common.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,GAIT,MAAM,cAAc,CAAC;AAQtB,wEAAwE;AACxE,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,EAAiB,CAAC,MAAM,EAAE,CAAC;AAErD,mCAAmC;AACnC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;AAerC;;;;;GAKG;AACH,yFAAyF;AACzF,+FAA+F;AAC/F,+FAA+F;AAC/F,0BAA0B;AAC1B,MAAM,UAAU,iBAAiB,CAC/B,SAAqC,EACrC,KAAoC,EACpC,MAAuC;IAEvC,OACE,CAAC,CAAC,SAAS;SACR,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,MAAM,CAAC;QACf,2BAA2B;SAC1B,QAAQ,CAAC,SAAgB,CAC7B,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,SAAqC,EACrC,KAAoC,EACpC,MAAuC;IAEvC,OACE,CAAC,CAAC,SAAS;SACR,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,MAAM,CAAC;QACf,2BAA2B;SAC1B,KAAK,CAAC,SAAgB,CAC1B,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,SAAqC,EACrC,KAAoC,EACpC,MAAuC;IAEvC,OACE,CAAC,CAAC,SAAS;SACR,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,MAAM,CAAC;QACf,2BAA2B;SAC1B,YAAY,CAAC,SAAgB,CACjC,CAAC;AACJ,CAAC","sourcesContent":["import {\n initTRPC,\n type TRPCMutationProcedure,\n type TRPCQueryProcedure,\n type TRPCSubscriptionProcedure,\n} from '@trpc/server';\nimport type { Context } from '../types/Context.js';\nimport type { z } from 'zod/v4-mini';\nimport type { ApiParams } from '../types/ApiParams.js';\nimport type { Session } from '@ms-cloudpack/common-types';\n\nexport type CreateContext = () => Promise<Context>;\n\n// Initialization of tRPC backend. Should be done only once per backend!\nconst t = initTRPC.context<CreateContext>().create();\n\n/** Reusable TRPC router helper. */\nexport const createRouter = t.router;\n\n/**\n * Generic procedure supertype for the procedure helpers. This should only be used in defining\n * procedure helpers (not as a type on functions) because it expects all Context/Session keys\n * rather than narrowing to only the ones used.\n */\ntype Procedure<TInput, TOutput> = (opts: ApiParams<TInput, keyof Context, keyof Session>) => TOutput | Promise<TOutput>;\n\n/**\n * tRPC procedure definition type. `metadata` is marked as `never` because we're not currently\n * using the `.metadata()` feature of procedures (could be added later).\n */\ntype ProcedureDef<TInput, TOutput> = { input: TInput; output: TOutput; meta: never };\n\n/**\n * Mutation procedure helper for tRPC.\n *\n * It's recommended to explicitly specify the type parameters to ensure the original types\n * and any docs are preserved in the procedures exposed on the client.\n */\n// These helpers exist because for some reason the generic input/output type inference in\n// `t.procedure.mutation` etc (maybe when combined with the way zod defines input/output types)\n// loses the original types during declaration emit, and instead emits copies with all the same\n// properties but no docs.\nexport function mutationProcedure<TInput, TOutput>(\n procedure: Procedure<TInput, TOutput>,\n input: z.ZodMiniType<TInput, TInput>,\n output: z.ZodMiniType<TOutput, TOutput>,\n): TRPCMutationProcedure<ProcedureDef<TInput, TOutput>> {\n return (\n t.procedure\n .input(input)\n .output(output)\n // eslint-disable-next-line\n .mutation(procedure as any) as TRPCMutationProcedure<ProcedureDef<TInput, TOutput>>\n );\n}\n\n/**\n * Query procedure helper for tRPC.\n *\n * It's recommended to explicitly specify the type parameters to ensure the original types\n * and any docs are preserved in the procedures exposed on the client.\n */\nexport function queryProcedure<TInput, TOutput>(\n procedure: Procedure<TInput, TOutput>,\n input: z.ZodMiniType<TInput, TInput>,\n output: z.ZodMiniType<TOutput, TOutput>,\n): TRPCQueryProcedure<ProcedureDef<TInput, TOutput>> {\n return (\n t.procedure\n .input(input)\n .output(output)\n // eslint-disable-next-line\n .query(procedure as any) as TRPCQueryProcedure<ProcedureDef<TInput, TOutput>>\n );\n}\n\n/**\n * Subscription procedure helper for tRPC.\n *\n * It's recommended to explicitly specify the type parameters to ensure the original types\n * and any docs are preserved in the procedures exposed on the client.\n */\nexport function subscriptionProcedure<TInput, TOutput>(\n procedure: Procedure<TInput, TOutput>,\n input: z.ZodMiniType<TInput, TInput>,\n output: z.ZodMiniType<TOutput, TOutput>,\n): TRPCSubscriptionProcedure<ProcedureDef<TInput, TOutput>> {\n return (\n t.procedure\n .input(input)\n .output(output)\n // eslint-disable-next-line\n .subscription(procedure as any) as TRPCSubscriptionProcedure<ProcedureDef<TInput, TOutput>>\n );\n}\n"]}
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/trpc/common.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,GAIT,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,CAAC,EAAE,MAAM,aAAa,CAAC;AAQhC;;;GAGG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAiB,CAAC,MAAM,CAAC;IAC3D,cAAc,CAAC,IAAI;QACjB,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QAC9B,OAAO;YACL,GAAG,KAAK;YACR,OAAO;YACL,wFAAwF;YACxF,qFAAqF;YACrF,6DAA6D;YAC7D,KAAK,CAAC,IAAI,KAAK,aAAa,IAAI,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;gBACpE,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,KAAiB,CAAC;gBAC1C,CAAC,CAAC,KAAK,CAAC,OAAO;SACpB,CAAC;QACF,KAAK;IACP,CAAC;CACF,CAAC,CAAC;AAEH,mCAAmC;AACnC,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;AAexC;;;;;GAKG;AACH,yFAAyF;AACzF,+FAA+F;AAC/F,+FAA+F;AAC/F,0BAA0B;AAC1B,MAAM,UAAU,iBAAiB,CAC/B,SAAqC,EACrC,KAAoC,EACpC,MAAuC;IAEvC,OACE,IAAI,CAAC,SAAS;SACX,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,MAAM,CAAC;QACf,2BAA2B;SAC1B,QAAQ,CAAC,SAAgB,CAC7B,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,SAAqC,EACrC,KAAoC,EACpC,MAAuC;IAEvC,OACE,IAAI,CAAC,SAAS;SACX,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,MAAM,CAAC;QACf,2BAA2B;SAC1B,KAAK,CAAC,SAAgB,CAC1B,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,SAAqC,EACrC,KAAoC,EACpC,MAAuC;IAEvC,OACE,IAAI,CAAC,SAAS;SACX,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,MAAM,CAAC;QACf,2BAA2B;SAC1B,YAAY,CAAC,SAAgB,CACjC,CAAC;AACJ,CAAC","sourcesContent":["import {\n initTRPC,\n type TRPCMutationProcedure,\n type TRPCQueryProcedure,\n type TRPCSubscriptionProcedure,\n} from '@trpc/server';\nimport type { Context } from '../types/Context.js';\nimport { z } from 'zod/v4-mini';\nimport type { ApiParams } from '../types/ApiParams.js';\nimport type { Session } from '@ms-cloudpack/common-types';\n// eslint-disable-next-line @typescript-eslint/no-restricted-imports -- not exported from v4-mini\nimport type { ZodError } from 'zod/v4';\n\nexport type CreateContext = () => Promise<Context>;\n\n/**\n * tRPC backend (the initialization functions should only be called once).\n * Exported for testing.\n */\nexport const trpc = initTRPC.context<CreateContext>().create({\n errorFormatter(opts) {\n const { shape, error } = opts;\n return {\n ...shape,\n message:\n // For zod validation errors, make them more readable (can't use instanceof here because\n // ZodError is missing from the v4-mini exports; the actual class name is $ZodError).\n // This is tested in the `getData` and `onDataChanged` tests.\n error.code === 'BAD_REQUEST' && error.cause?.name.endsWith('ZodError')\n ? z.prettifyError(error.cause as ZodError)\n : error.message,\n };\n // };\n },\n});\n\n/** Reusable TRPC router helper. */\nexport const createRouter = trpc.router;\n\n/**\n * Generic procedure supertype for the procedure helpers. This should only be used in defining\n * procedure helpers (not as a type on functions) because it expects all Context/Session keys\n * rather than narrowing to only the ones used.\n */\ntype Procedure<TInput, TOutput> = (opts: ApiParams<TInput, keyof Context, keyof Session>) => TOutput | Promise<TOutput>;\n\n/**\n * tRPC procedure definition type. `metadata` is marked as `never` because we're not currently\n * using the `.metadata()` feature of procedures (could be added later).\n */\ntype ProcedureDef<TInput, TOutput> = { input: TInput; output: TOutput; meta: never };\n\n/**\n * Mutation procedure helper for tRPC.\n *\n * It's recommended to explicitly specify the type parameters to ensure the original types\n * and any docs are preserved in the procedures exposed on the client.\n */\n// These helpers exist because for some reason the generic input/output type inference in\n// `t.procedure.mutation` etc (maybe when combined with the way zod defines input/output types)\n// loses the original types during declaration emit, and instead emits copies with all the same\n// properties but no docs.\nexport function mutationProcedure<TInput, TOutput>(\n procedure: Procedure<TInput, TOutput>,\n input: z.ZodMiniType<TInput, TInput>,\n output: z.ZodMiniType<TOutput, TOutput>,\n): TRPCMutationProcedure<ProcedureDef<TInput, TOutput>> {\n return (\n trpc.procedure\n .input(input)\n .output(output)\n // eslint-disable-next-line\n .mutation(procedure as any) as TRPCMutationProcedure<ProcedureDef<TInput, TOutput>>\n );\n}\n\n/**\n * Query procedure helper for tRPC.\n *\n * It's recommended to explicitly specify the type parameters to ensure the original types\n * and any docs are preserved in the procedures exposed on the client.\n */\nexport function queryProcedure<TInput, TOutput>(\n procedure: Procedure<TInput, TOutput>,\n input: z.ZodMiniType<TInput, TInput>,\n output: z.ZodMiniType<TOutput, TOutput>,\n): TRPCQueryProcedure<ProcedureDef<TInput, TOutput>> {\n return (\n trpc.procedure\n .input(input)\n .output(output)\n // eslint-disable-next-line\n .query(procedure as any) as TRPCQueryProcedure<ProcedureDef<TInput, TOutput>>\n );\n}\n\n/**\n * Subscription procedure helper for tRPC.\n *\n * It's recommended to explicitly specify the type parameters to ensure the original types\n * and any docs are preserved in the procedures exposed on the client.\n */\nexport function subscriptionProcedure<TInput, TOutput>(\n procedure: Procedure<TInput, TOutput>,\n input: z.ZodMiniType<TInput, TInput>,\n output: z.ZodMiniType<TOutput, TOutput>,\n): TRPCSubscriptionProcedure<ProcedureDef<TInput, TOutput>> {\n return (\n trpc.procedure\n .input(input)\n .output(output)\n // eslint-disable-next-line\n .subscription(procedure as any) as TRPCSubscriptionProcedure<ProcedureDef<TInput, TOutput>>\n );\n}\n"]}
@@ -8,7 +8,9 @@ export type CloudpackClient = TRPCClient<AppRouter> & {
8
8
  * Creates a cloudpack client that can be used to communicate with the cloudpack server using trpc.
9
9
  */
10
10
  export declare function createCloudpackClient(options: {
11
+ /** API server URL (`ws:` or `wss:`) */
11
12
  url: string;
13
+ /** Task reporter for use on the server */
12
14
  reporter?: TaskReporter;
13
15
  }): Promise<CloudpackClient>;
14
16
  //# sourceMappingURL=createCloudpackClient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createCloudpackClient.d.ts","sourceRoot":"","sources":["../../src/trpc/createCloudpackClient.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG;IACpD,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB,GAAG,OAAO,CAAC,eAAe,CAAC,CAgD3B"}
1
+ {"version":3,"file":"createCloudpackClient.d.ts","sourceRoot":"","sources":["../../src/trpc/createCloudpackClient.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG;IACpD,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE;IACnD,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB,GAAG,OAAO,CAAC,eAAe,CAAC,CAuE3B"}
@@ -6,18 +6,25 @@ import { ignoreSelfSignedCertErrors } from '../utilities/ignoreSelfSignedCertErr
6
6
  * Creates a cloudpack client that can be used to communicate with the cloudpack server using trpc.
7
7
  */
8
8
  export async function createCloudpackClient(options) {
9
+ const { url: wsUrl, reporter } = options;
9
10
  // We polyfill websocket in node conditions.
10
11
  await ensureWebsocketDefined();
11
- ignoreSelfSignedCertErrors({ reporter: options.reporter });
12
+ ignoreSelfSignedCertErrors({ reporter });
12
13
  // Create the client.
13
- const wsClient = createWSClient(options);
14
- const tempUrl = makeUrl(options.url);
14
+ const wsClient = createWSClient({
15
+ url: wsUrl,
16
+ onError: (evt) => {
17
+ console.error('[Cloudpack] Unexpected websocket client error:', evt);
18
+ },
19
+ });
20
+ const tempUrl = makeUrl(wsUrl);
15
21
  // Replace the protocol with http so that we can use the same url for http requests.
16
22
  const isSSL = tempUrl.protocol === 'wss:';
17
23
  tempUrl.protocol = isSSL ? 'https:' : 'http:';
18
- const url = tempUrl.toString().replace(/\/$/, '');
24
+ const httpUrl = tempUrl.toString().replace(/\/$/, '');
19
25
  const client = createTRPCClient({
20
26
  links: [
27
+ // send subscriptions to the websocket client and handle operations with HTTP requests
21
28
  splitLink({
22
29
  condition(op) {
23
30
  return op.type === 'subscription';
@@ -26,7 +33,7 @@ export async function createCloudpackClient(options) {
26
33
  client: wsClient,
27
34
  }),
28
35
  false: httpBatchLink({
29
- url,
36
+ url: httpUrl,
30
37
  }),
31
38
  }),
32
39
  ],
@@ -34,10 +41,22 @@ export async function createCloudpackClient(options) {
34
41
  const close = async () => {
35
42
  await wsClient.close();
36
43
  };
44
+ // Add a default onError handler for onDataChanged subscriptions.
45
+ // Otherwise errors (such as from zod type violations) will be hidden.
46
+ const onDataChanged = {
47
+ subscribe: (source, opts) => {
48
+ opts = { ...opts };
49
+ opts.onError ??= (err) => {
50
+ console.error(`[Cloudpack] Error in ${source.path.join('.')} data subscription (this may be a Cloudpack bug): ` +
51
+ err.message);
52
+ };
53
+ return client.onDataChanged.subscribe(source, opts);
54
+ },
55
+ };
37
56
  // Ugh. This is a hack to get around the fact that the client is a proxy.
38
- // Make another proxy which defines the close method and passes through everything else
39
- // to the original client.
40
- return new Proxy({ close }, {
57
+ // Make another proxy which defines the close method and onDataChanged wrapper,
58
+ // and passes through everything else to the original client.
59
+ return new Proxy({ close, onDataChanged }, {
41
60
  get(target, prop) {
42
61
  // eslint-disable-next-line no-prototype-builtins
43
62
  if (target.hasOwnProperty(prop)) {
@@ -1 +1 @@
1
- {"version":3,"file":"createCloudpackClient.js","sourceRoot":"","sources":["../../src/trpc/createCloudpackClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAC;AAG5D,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAClG,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,0BAA0B,EAAE,MAAM,4CAA4C,CAAC;AAOxF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAG3C;IACC,4CAA4C;IAC5C,MAAM,sBAAsB,EAAE,CAAC;IAE/B,0BAA0B,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE3D,qBAAqB;IACrB,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAErC,oFAAoF;IACpF,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC;IAC1C,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IAE9C,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,gBAAgB,CAAY;QACzC,KAAK,EAAE;YACL,SAAS,CAAC;gBACR,SAAS,CAAC,EAAE;oBACV,OAAO,EAAE,CAAC,IAAI,KAAK,cAAc,CAAC;gBACpC,CAAC;gBACD,IAAI,EAAE,MAAM,CAAC;oBACX,MAAM,EAAE,QAAQ;iBACjB,CAAC;gBACF,KAAK,EAAE,aAAa,CAAC;oBACnB,GAAG;iBACJ,CAAC;aACH,CAAC;SACH;KACF,CAAC,CAAC;IAEH,MAAM,KAAK,GAA6B,KAAK,IAAI,EAAE;QACjD,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC,CAAC;IAEF,yEAAyE;IACzE,uFAAuF;IACvF,0BAA0B;IAC1B,OAAO,IAAI,KAAK,CAAkB,EAAE,KAAK,EAAqB,EAAE;QAC9D,GAAG,CAAC,MAAM,EAAE,IAAI;YACd,iDAAiD;YACjD,IAAI,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChC,OAAO,MAAM,CAAC,IAA2B,CAAC,CAAC;YAC7C,CAAC;YAED,OAAO,MAAM,CAAC,IAA+C,CAAC,CAAC;QACjE,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { makeUrl } from '@ms-cloudpack/path-string-parsing';\nimport type { TaskReporter } from '@ms-cloudpack/task-reporter';\nimport type { TRPCClient } from '@trpc/client';\nimport { createTRPCClient, createWSClient, httpBatchLink, splitLink, wsLink } from '@trpc/client';\nimport { ensureWebsocketDefined } from '../utilities/ensureWebsocketDefined.js';\nimport { ignoreSelfSignedCertErrors } from '../utilities/ignoreSelfSignedCertErrors.js';\nimport type { AppRouter } from '../types/AppRouter.js';\n\nexport type CloudpackClient = TRPCClient<AppRouter> & {\n close: () => Promise<void>;\n};\n\n/**\n * Creates a cloudpack client that can be used to communicate with the cloudpack server using trpc.\n */\nexport async function createCloudpackClient(options: {\n url: string;\n reporter?: TaskReporter;\n}): Promise<CloudpackClient> {\n // We polyfill websocket in node conditions.\n await ensureWebsocketDefined();\n\n ignoreSelfSignedCertErrors({ reporter: options.reporter });\n\n // Create the client.\n const wsClient = createWSClient(options);\n const tempUrl = makeUrl(options.url);\n\n // Replace the protocol with http so that we can use the same url for http requests.\n const isSSL = tempUrl.protocol === 'wss:';\n tempUrl.protocol = isSSL ? 'https:' : 'http:';\n\n const url = tempUrl.toString().replace(/\\/$/, '');\n const client = createTRPCClient<AppRouter>({\n links: [\n splitLink({\n condition(op) {\n return op.type === 'subscription';\n },\n true: wsLink({\n client: wsClient,\n }),\n false: httpBatchLink({\n url,\n }),\n }),\n ],\n });\n\n const close: CloudpackClient['close'] = async () => {\n await wsClient.close();\n };\n\n // Ugh. This is a hack to get around the fact that the client is a proxy.\n // Make another proxy which defines the close method and passes through everything else\n // to the original client.\n return new Proxy<CloudpackClient>({ close } as CloudpackClient, {\n get(target, prop) {\n // eslint-disable-next-line no-prototype-builtins\n if (target.hasOwnProperty(prop)) {\n return target[prop as keyof typeof target];\n }\n\n return client[prop as Exclude<keyof CloudpackClient, 'close'>];\n },\n });\n}\n"]}
1
+ {"version":3,"file":"createCloudpackClient.js","sourceRoot":"","sources":["../../src/trpc/createCloudpackClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAC;AAG5D,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAClG,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,0BAA0B,EAAE,MAAM,4CAA4C,CAAC;AAOxF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAK3C;IACC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAEzC,4CAA4C;IAC5C,MAAM,sBAAsB,EAAE,CAAC;IAE/B,0BAA0B,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEzC,qBAAqB;IACrB,MAAM,QAAQ,GAAG,cAAc,CAAC;QAC9B,GAAG,EAAE,KAAK;QACV,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACf,OAAO,CAAC,KAAK,CAAC,gDAAgD,EAAE,GAAG,CAAC,CAAC;QACvE,CAAC;KACF,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAE/B,oFAAoF;IACpF,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC;IAC1C,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IAE9C,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,gBAAgB,CAAY;QACzC,KAAK,EAAE;YACL,sFAAsF;YACtF,SAAS,CAAC;gBACR,SAAS,CAAC,EAAE;oBACV,OAAO,EAAE,CAAC,IAAI,KAAK,cAAc,CAAC;gBACpC,CAAC;gBACD,IAAI,EAAE,MAAM,CAAC;oBACX,MAAM,EAAE,QAAQ;iBACjB,CAAC;gBACF,KAAK,EAAE,aAAa,CAAC;oBACnB,GAAG,EAAE,OAAO;iBACb,CAAC;aACH,CAAC;SACH;KACF,CAAC,CAAC;IAEH,MAAM,KAAK,GAA6B,KAAK,IAAI,EAAE;QACjD,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC,CAAC;IAEF,iEAAiE;IACjE,sEAAsE;IACtE,MAAM,aAAa,GAAqC;QACtD,SAAS,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;YAC1B,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;YACnB,IAAI,CAAC,OAAO,KAAK,CAAC,GAAG,EAAE,EAAE;gBACvB,OAAO,CAAC,KAAK,CACX,wBAAwB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,oDAAoD;oBAC/F,GAAG,CAAC,OAAO,CACd,CAAC;YACJ,CAAC,CAAC;YACF,OAAO,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACtD,CAAC;KACF,CAAC;IAEF,yEAAyE;IACzE,+EAA+E;IAC/E,6DAA6D;IAC7D,OAAO,IAAI,KAAK,CAAkB,EAAE,KAAK,EAAE,aAAa,EAAqB,EAAE;QAC7E,GAAG,CAAC,MAAM,EAAE,IAAI;YACd,iDAAiD;YACjD,IAAI,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChC,OAAO,MAAM,CAAC,IAA2B,CAAC,CAAC;YAC7C,CAAC;YAED,OAAO,MAAM,CAAC,IAA+C,CAAC,CAAC;QACjE,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { makeUrl } from '@ms-cloudpack/path-string-parsing';\nimport type { TaskReporter } from '@ms-cloudpack/task-reporter';\nimport type { TRPCClient } from '@trpc/client';\nimport { createTRPCClient, createWSClient, httpBatchLink, splitLink, wsLink } from '@trpc/client';\nimport { ensureWebsocketDefined } from '../utilities/ensureWebsocketDefined.js';\nimport { ignoreSelfSignedCertErrors } from '../utilities/ignoreSelfSignedCertErrors.js';\nimport type { AppRouter } from '../types/AppRouter.js';\n\nexport type CloudpackClient = TRPCClient<AppRouter> & {\n close: () => Promise<void>;\n};\n\n/**\n * Creates a cloudpack client that can be used to communicate with the cloudpack server using trpc.\n */\nexport async function createCloudpackClient(options: {\n /** API server URL (`ws:` or `wss:`) */\n url: string;\n /** Task reporter for use on the server */\n reporter?: TaskReporter;\n}): Promise<CloudpackClient> {\n const { url: wsUrl, reporter } = options;\n\n // We polyfill websocket in node conditions.\n await ensureWebsocketDefined();\n\n ignoreSelfSignedCertErrors({ reporter });\n\n // Create the client.\n const wsClient = createWSClient({\n url: wsUrl,\n onError: (evt) => {\n console.error('[Cloudpack] Unexpected websocket client error:', evt);\n },\n });\n const tempUrl = makeUrl(wsUrl);\n\n // Replace the protocol with http so that we can use the same url for http requests.\n const isSSL = tempUrl.protocol === 'wss:';\n tempUrl.protocol = isSSL ? 'https:' : 'http:';\n\n const httpUrl = tempUrl.toString().replace(/\\/$/, '');\n const client = createTRPCClient<AppRouter>({\n links: [\n // send subscriptions to the websocket client and handle operations with HTTP requests\n splitLink({\n condition(op) {\n return op.type === 'subscription';\n },\n true: wsLink({\n client: wsClient,\n }),\n false: httpBatchLink({\n url: httpUrl,\n }),\n }),\n ],\n });\n\n const close: CloudpackClient['close'] = async () => {\n await wsClient.close();\n };\n\n // Add a default onError handler for onDataChanged subscriptions.\n // Otherwise errors (such as from zod type violations) will be hidden.\n const onDataChanged: CloudpackClient['onDataChanged'] = {\n subscribe: (source, opts) => {\n opts = { ...opts };\n opts.onError ??= (err) => {\n console.error(\n `[Cloudpack] Error in ${source.path.join('.')} data subscription (this may be a Cloudpack bug): ` +\n err.message,\n );\n };\n return client.onDataChanged.subscribe(source, opts);\n },\n };\n\n // Ugh. This is a hack to get around the fact that the client is a proxy.\n // Make another proxy which defines the close method and onDataChanged wrapper,\n // and passes through everything else to the original client.\n return new Proxy<CloudpackClient>({ close, onDataChanged } as CloudpackClient, {\n get(target, prop) {\n // eslint-disable-next-line no-prototype-builtins\n if (target.hasOwnProperty(prop)) {\n return target[prop as keyof typeof target];\n }\n\n return client[prop as Exclude<keyof CloudpackClient, 'close'>];\n },\n });\n}\n"]}
@@ -1,9 +1,10 @@
1
1
  import { WebSocketServer } from 'ws';
2
2
  import type { Context } from '../types/Context.js';
3
- export interface CloudpackServer {
3
+ export interface CloudpackServer extends Pick<WebSocketServer, 'clients'> {
4
+ /** Full server root URL, including protocol and port */
4
5
  url: string;
6
+ /** Close the server. Does nothing if called multiple times. */
5
7
  close: () => Promise<void>;
6
- clients: WebSocketServer['clients'];
7
8
  }
8
9
  export declare const apiServerPort: number[];
9
10
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"createCloudpackServer.d.ts","sourceRoot":"","sources":["../../src/trpc/createCloudpackServer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAIrC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAKnD,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;CACrC;AAED,eAAO,MAAM,aAAa,UAA2B,CAAC;AAEtD;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE;IACP,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC1B,EACD,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,eAAe,CAAC,CAmD1B"}
1
+ {"version":3,"file":"createCloudpackServer.d.ts","sourceRoot":"","sources":["../../src/trpc/createCloudpackServer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAIrC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAKnD,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC;IACvE,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ,+DAA+D;IAC/D,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,eAAO,MAAM,aAAa,UAA2B,CAAC;AAEtD;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE;IACP,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC1B,EACD,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,eAAe,CAAC,CAoE1B"}
@@ -29,6 +29,16 @@ export async function createCloudpackServer(options, context) {
29
29
  createContext,
30
30
  https,
31
31
  cwd: context.session.config.appPath,
32
+ // This happens when an error is thrown internally in a procedure, and possibly other cases
33
+ // (but not for subscription data validation errors).
34
+ onError: (err) => {
35
+ console.debug([
36
+ `Error in Cloudpack API server ${err.path}:`,
37
+ `Input: ${JSON.stringify(err.input, null, 2)}`,
38
+ `Error: ${err.error.stack || err.error.message}`,
39
+ `Details: ${JSON.stringify(err.error, null, 2)}`,
40
+ ].join('\n'));
41
+ },
32
42
  });
33
43
  await listen(port, hostname);
34
44
  const wss = new WebSocketServer({ server });
@@ -40,9 +50,13 @@ export async function createCloudpackServer(options, context) {
40
50
  const webSocketProtocol = https ? 'wss' : 'ws';
41
51
  const url = `${webSocketProtocol}://${hostname}:${port}`;
42
52
  context.session.urls.apiServer = url;
53
+ let closed = false;
43
54
  return {
44
55
  url,
45
56
  close: async () => {
57
+ if (closed)
58
+ return;
59
+ closed = true;
46
60
  await new Promise((resolve, reject) => {
47
61
  wss.clients.forEach((socket) => socket.terminate());
48
62
  wss.close((err) => (err ? reject(err) : resolve()));
@@ -1 +1 @@
1
- {"version":3,"file":"createCloudpackServer.js","sourceRoot":"","sources":["../../src/trpc/createCloudpackServer.ts"],"names":[],"mappings":"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","sourcesContent":["import { applyWSSHandler } from '@trpc/server/adapters/ws';\nimport getPort from 'get-port';\nimport { WebSocketServer } from 'ws';\nimport { createHTTPServer } from './httpAdapter.js';\nimport cors from 'cors';\nimport { getDomain } from '@ms-cloudpack/create-express-app';\nimport type { Context } from '../types/Context.js';\nimport * as apis from '../apis/index.js';\nimport { createRouter } from './common.js';\nimport type { AppRouter } from '../types/AppRouter.js';\n\nexport interface CloudpackServer {\n url: string;\n close: () => Promise<void>;\n clients: WebSocketServer['clients'];\n}\n\nexport const apiServerPort = [9890, 9891, 9892, 9893];\n\n/**\n * Creates a cloudpack server that can be used to communicate with the cloudpack client using trpc.\n */\nexport async function createCloudpackServer(\n options: {\n /** Custom port(s) to try for the API server. */\n port?: number | number[];\n },\n context: Context,\n): Promise<CloudpackServer> {\n const portArg = Array.isArray(options.port) ? options.port : options.port ? [options.port] : undefined;\n const port = await getPort({ port: portArg || apiServerPort });\n if (portArg && !portArg.includes(port)) {\n throw new Error(`No ports from range ${JSON.stringify(portArg)} are available`);\n }\n\n const createContext = () => Promise.resolve(context);\n const hostname = getDomain(context.session.config?.server?.domain);\n const https = context.session.config?.server?.parsedHttps ?? context.session.config?.server?.https;\n\n const procedures = Object.fromEntries(Object.entries(apis).map(([name, api]) => [name, api.procedure]));\n // AppRouter is the correct type, but doesn't get inferred correctly after Object.entries\n const router = createRouter(procedures) as unknown as AppRouter;\n\n const { server, listen } = await createHTTPServer({\n domain: hostname,\n middleware: cors(),\n router,\n createContext,\n https,\n cwd: context.session.config.appPath,\n });\n\n await listen(port, hostname);\n\n const wss = new WebSocketServer({ server });\n\n applyWSSHandler<AppRouter>({\n wss,\n router,\n createContext,\n });\n\n const webSocketProtocol = https ? 'wss' : 'ws';\n const url = `${webSocketProtocol}://${hostname}:${port}`;\n context.session.urls.apiServer = url;\n\n return {\n url,\n close: async () => {\n await new Promise<void>((resolve, reject) => {\n wss.clients.forEach((socket) => socket.terminate());\n wss.close((err) => (err ? reject(err) : resolve()));\n server.close();\n });\n },\n get clients() {\n return wss.clients;\n },\n };\n}\n"]}
1
+ {"version":3,"file":"createCloudpackServer.js","sourceRoot":"","sources":["../../src/trpc/createCloudpackServer.ts"],"names":[],"mappings":"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","sourcesContent":["import { applyWSSHandler } from '@trpc/server/adapters/ws';\nimport getPort from 'get-port';\nimport { WebSocketServer } from 'ws';\nimport { createHTTPServer } from './httpAdapter.js';\nimport cors from 'cors';\nimport { getDomain } from '@ms-cloudpack/create-express-app';\nimport type { Context } from '../types/Context.js';\nimport * as apis from '../apis/index.js';\nimport { createRouter } from './common.js';\nimport type { AppRouter } from '../types/AppRouter.js';\n\nexport interface CloudpackServer extends Pick<WebSocketServer, 'clients'> {\n /** Full server root URL, including protocol and port */\n url: string;\n /** Close the server. Does nothing if called multiple times. */\n close: () => Promise<void>;\n}\n\nexport const apiServerPort = [9890, 9891, 9892, 9893];\n\n/**\n * Creates a cloudpack server that can be used to communicate with the cloudpack client using trpc.\n */\nexport async function createCloudpackServer(\n options: {\n /** Custom port(s) to try for the API server. */\n port?: number | number[];\n },\n context: Context,\n): Promise<CloudpackServer> {\n const portArg = Array.isArray(options.port) ? options.port : options.port ? [options.port] : undefined;\n const port = await getPort({ port: portArg || apiServerPort });\n if (portArg && !portArg.includes(port)) {\n throw new Error(`No ports from range ${JSON.stringify(portArg)} are available`);\n }\n\n const createContext = () => Promise.resolve(context);\n const hostname = getDomain(context.session.config?.server?.domain);\n const https = context.session.config?.server?.parsedHttps ?? context.session.config?.server?.https;\n\n const procedures = Object.fromEntries(Object.entries(apis).map(([name, api]) => [name, api.procedure]));\n // AppRouter is the correct type, but doesn't get inferred correctly after Object.entries\n const router = createRouter(procedures) as unknown as AppRouter;\n\n const { server, listen } = await createHTTPServer({\n domain: hostname,\n middleware: cors(),\n router,\n createContext,\n https,\n cwd: context.session.config.appPath,\n // This happens when an error is thrown internally in a procedure, and possibly other cases\n // (but not for subscription data validation errors).\n onError: (err) => {\n console.debug(\n [\n `Error in Cloudpack API server ${err.path}:`,\n `Input: ${JSON.stringify(err.input, null, 2)}`,\n `Error: ${err.error.stack || err.error.message}`,\n `Details: ${JSON.stringify(err.error, null, 2)}`,\n ].join('\\n'),\n );\n },\n });\n\n await listen(port, hostname);\n\n const wss = new WebSocketServer({ server });\n\n applyWSSHandler<AppRouter>({\n wss,\n router,\n createContext,\n });\n\n const webSocketProtocol = https ? 'wss' : 'ws';\n const url = `${webSocketProtocol}://${hostname}:${port}`;\n context.session.urls.apiServer = url;\n\n let closed = false;\n\n return {\n url,\n close: async () => {\n if (closed) return;\n closed = true;\n\n await new Promise<void>((resolve, reject) => {\n wss.clients.forEach((socket) => socket.terminate());\n wss.close((err) => (err ? reject(err) : resolve()));\n server.close();\n });\n },\n get clients() {\n return wss.clients;\n },\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function getTestPort(filename: string): number;
2
+ //# sourceMappingURL=getTestPort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getTestPort.d.ts","sourceRoot":"","sources":["../../src/trpc/getTestPort.ts"],"names":[],"mappings":"AAQA,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOpD"}
@@ -0,0 +1,15 @@
1
+ import path from 'path';
2
+ const filenames = {
3
+ 'getData.test.ts': 9890,
4
+ 'onDataChanged.test.ts': 9891,
5
+ 'publishData.test.ts': 9892,
6
+ };
7
+ export function getTestPort(filename) {
8
+ filename = path.basename(filename);
9
+ const port = filenames[filename];
10
+ if (!port) {
11
+ throw new Error(`No test port defined for ${filename} (please add one)`);
12
+ }
13
+ return port;
14
+ }
15
+ //# sourceMappingURL=getTestPort.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getTestPort.js","sourceRoot":"","sources":["../../src/trpc/getTestPort.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,SAAS,GAA2B;IACxC,iBAAiB,EAAE,IAAI;IACvB,uBAAuB,EAAE,IAAI;IAC7B,qBAAqB,EAAE,IAAI;CAC5B,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,mBAAmB,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import path from 'path';\n\nconst filenames: Record<string, number> = {\n 'getData.test.ts': 9890,\n 'onDataChanged.test.ts': 9891,\n 'publishData.test.ts': 9892,\n};\n\nexport function getTestPort(filename: string): number {\n filename = path.basename(filename);\n const port = filenames[filename];\n if (!port) {\n throw new Error(`No test port defined for ${filename} (please add one)`);\n }\n return port;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"matchingZodObject.d.ts","sourceRoot":"","sources":["../../src/utilities/matchingZodObject.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,aAAa,CAAC;AAEhC;;;GAGG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,MAAM,IAAI;KAG9C,CAAC,IAAI,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,GAE1C,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAC5C,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;CAC9B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,SAAS,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,8DAE3F;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,SAAS,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,8DAEhG"}
1
+ {"version":3,"file":"matchingZodObject.d.ts","sourceRoot":"","sources":["../../src/utilities/matchingZodObject.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,aAAa,CAAC;AAMhC;;;GAGG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,MAAM,IAAI;KAG9C,CAAC,IAAI,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,GAE1C,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAC5C,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;CAC9B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,SAAS,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,8DAE3F;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,SAAS,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,8DAEhG"}
@@ -1,5 +1,8 @@
1
1
  /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
2
2
  import { z } from 'zod/v4-mini';
3
+ import enLocale from 'zod/v4/locales/en.js';
4
+ // Enable parse error messages
5
+ z.config(enLocale());
3
6
  /**
4
7
  * Get a Zod object that matches the expected type, including any optional properties.
5
8
  * (Does not provide the same guarantee for nested object types.)
@@ -1 +1 @@
1
- {"version":3,"file":"matchingZodObject.js","sourceRoot":"","sources":["../../src/utilities/matchingZodObject.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,OAAO,EAAE,CAAC,EAAE,MAAM,aAAa,CAAC;AAehC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAA0B,KAAiC;IAC1F,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAA0B,KAAiC;IAC/F,OAAO,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\nimport { z } from 'zod/v4-mini';\n\n/**\n * Zod shape object matching type `T`, with any optional properties remapped to required properties\n * with type `originalType | undefined`.\n */\nexport type MatchingZodShape<T extends object> = {\n // Use Required<T> in the mapping to ensure that all properties (including optional) are\n // included in the input zod shape.\n [K in keyof Required<T>]: Omit<T, K> extends T\n ? // If K is optional in T, make it a ZodOptional\n z.ZodMiniOptional<z.ZodMiniType<T[K], T[K]>>\n : z.ZodMiniType<T[K], T[K]>;\n};\n\n/**\n * Get a Zod object that matches the expected type, including any optional properties.\n * (Does not provide the same guarantee for nested object types.)\n *\n * Unrecognized properties will be stripped/ignored at runtime.\n * To preserve them, use `matchingZodObjectLoose` instead.\n *\n * Using this helper instead of `const ZodFoo = z.object({...}); type Foo = z.infer<typeof ZodFoo>;`\n * is recommended in cases where the original type is defined elsewhere (such as in `common-types`),\n * to ensure all the properties stay in sync.\n */\nexport function matchingZodObject<Expected extends object>(shape: MatchingZodShape<Expected>) {\n return z.object(shape);\n}\n\n/**\n * Like `matchingZodObject`, but pass through any extra properties that aren't defined in the shape.\n *\n * See `matchingZodObject` comment for more details.\n */\nexport function matchingZodObjectLoose<Expected extends object>(shape: MatchingZodShape<Expected>) {\n return z.looseObject(shape);\n}\n"]}
1
+ {"version":3,"file":"matchingZodObject.js","sourceRoot":"","sources":["../../src/utilities/matchingZodObject.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,OAAO,EAAE,CAAC,EAAE,MAAM,aAAa,CAAC;AAChC,OAAO,QAAQ,MAAM,sBAAsB,CAAC;AAE5C,8BAA8B;AAC9B,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;AAerB;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAA0B,KAAiC;IAC1F,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAA0B,KAAiC;IAC/F,OAAO,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\nimport { z } from 'zod/v4-mini';\nimport enLocale from 'zod/v4/locales/en.js';\n\n// Enable parse error messages\nz.config(enLocale());\n\n/**\n * Zod shape object matching type `T`, with any optional properties remapped to required properties\n * with type `originalType | undefined`.\n */\nexport type MatchingZodShape<T extends object> = {\n // Use Required<T> in the mapping to ensure that all properties (including optional) are\n // included in the input zod shape.\n [K in keyof Required<T>]: Omit<T, K> extends T\n ? // If K is optional in T, make it a ZodOptional\n z.ZodMiniOptional<z.ZodMiniType<T[K], T[K]>>\n : z.ZodMiniType<T[K], T[K]>;\n};\n\n/**\n * Get a Zod object that matches the expected type, including any optional properties.\n * (Does not provide the same guarantee for nested object types.)\n *\n * Unrecognized properties will be stripped/ignored at runtime.\n * To preserve them, use `matchingZodObjectLoose` instead.\n *\n * Using this helper instead of `const ZodFoo = z.object({...}); type Foo = z.infer<typeof ZodFoo>;`\n * is recommended in cases where the original type is defined elsewhere (such as in `common-types`),\n * to ensure all the properties stay in sync.\n */\nexport function matchingZodObject<Expected extends object>(shape: MatchingZodShape<Expected>) {\n return z.object(shape);\n}\n\n/**\n * Like `matchingZodObject`, but pass through any extra properties that aren't defined in the shape.\n *\n * See `matchingZodObject` comment for more details.\n */\nexport function matchingZodObjectLoose<Expected extends object>(shape: MatchingZodShape<Expected>) {\n return z.looseObject(shape);\n}\n"]}
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "@ms-cloudpack/api-server",
3
- "version": "0.64.1",
3
+ "version": "0.64.3",
4
4
  "description": "An implementation of the API server that does interacts with a task scheduler.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "types": "./lib/index.d.ts",
8
- "sideEffects": false,
8
+ "sideEffects": [
9
+ "./lib/utilities/matchingZodObject.js"
10
+ ],
9
11
  "exports": {
10
12
  ".": {
11
13
  "node": {
@@ -23,23 +25,23 @@
23
25
  }
24
26
  },
25
27
  "dependencies": {
26
- "@ms-cloudpack/bundler": "^0.25.15",
27
- "@ms-cloudpack/common-types": "^0.25.1",
28
- "@ms-cloudpack/config": "^0.35.12",
29
- "@ms-cloudpack/create-express-app": "^1.10.37",
28
+ "@ms-cloudpack/bundler": "^0.25.17",
29
+ "@ms-cloudpack/common-types": "^0.26.0",
30
+ "@ms-cloudpack/config": "^0.35.14",
31
+ "@ms-cloudpack/create-express-app": "^1.10.39",
30
32
  "@ms-cloudpack/data-bus": "^0.5.0",
31
33
  "@ms-cloudpack/environment": "^0.1.1",
32
- "@ms-cloudpack/esm-stub-utilities": "^0.15.1",
33
- "@ms-cloudpack/file-watcher": "^0.3.8",
34
- "@ms-cloudpack/import-map": "^0.10.30",
34
+ "@ms-cloudpack/esm-stub-utilities": "^0.15.3",
35
+ "@ms-cloudpack/file-watcher": "^0.3.10",
36
+ "@ms-cloudpack/import-map": "^0.10.32",
35
37
  "@ms-cloudpack/json-utilities": "^0.1.10",
36
- "@ms-cloudpack/package-hashes": "^0.8.13",
37
- "@ms-cloudpack/package-utilities": "^12.3.14",
38
+ "@ms-cloudpack/package-hashes": "^0.8.15",
39
+ "@ms-cloudpack/package-utilities": "^12.3.16",
38
40
  "@ms-cloudpack/path-string-parsing": "^1.2.7",
39
- "@ms-cloudpack/path-utilities": "^3.1.8",
40
- "@ms-cloudpack/remote-cache": "^0.11.24",
41
+ "@ms-cloudpack/path-utilities": "^3.1.10",
42
+ "@ms-cloudpack/remote-cache": "^0.11.26",
41
43
  "@ms-cloudpack/task-reporter": "^0.17.2",
42
- "@ms-cloudpack/telemetry": "^0.11.26",
44
+ "@ms-cloudpack/telemetry": "^0.11.28",
43
45
  "@trpc/client": "^11.1.1",
44
46
  "@trpc/server": "^11.1.1",
45
47
  "cors": "^2.8.5",
@@ -1,8 +0,0 @@
1
- import type { DataBus } from '@ms-cloudpack/data-bus';
2
- import type { TRPCClient } from '@trpc/client';
3
- import type { AppRouter } from '../types/AppRouter.js';
4
- export declare function connectBusToClient(params: {
5
- bus: DataBus;
6
- client: TRPCClient<AppRouter>;
7
- }): void;
8
- //# sourceMappingURL=connectBusToClient.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"connectBusToClient.d.ts","sourceRoot":"","sources":["../../src/trpc/connectBusToClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,UAAU,CAAC,SAAS,CAAC,CAAA;CAAE,GAAG,IAAI,CA4BhG"}
@@ -1,26 +0,0 @@
1
- export function connectBusToClient(params) {
2
- const { bus, client } = params;
3
- const subIds = {};
4
- bus.addProvider({
5
- path: [],
6
- onActivate: ({ path }) => {
7
- const id = path.join('/');
8
- const onData = (value) => {
9
- bus.publish(path, value);
10
- };
11
- client.getData
12
- .query({ path })
13
- .then(onData)
14
- .catch(() => {
15
- /* no-op */
16
- });
17
- subIds[id] = client.onDataChanged.subscribe({ path }, { onData });
18
- },
19
- onDeactivate: ({ path }) => {
20
- const id = path.join('/');
21
- subIds[id].unsubscribe();
22
- delete subIds[id];
23
- },
24
- });
25
- }
26
- //# sourceMappingURL=connectBusToClient.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"connectBusToClient.js","sourceRoot":"","sources":["../../src/trpc/connectBusToClient.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,kBAAkB,CAAC,MAAuD;IACxF,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC/B,MAAM,MAAM,GAAmC,EAAE,CAAC;IAElD,GAAG,CAAC,WAAW,CAAC;QACd,IAAI,EAAE,EAAE;QACR,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;YACvB,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAE1B,MAAM,MAAM,GAAG,CAAC,KAAc,EAAE,EAAE;gBAChC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC3B,CAAC,CAAC;YAEF,MAAM,CAAC,OAAO;iBACX,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;iBACf,IAAI,CAAC,MAAM,CAAC;iBACZ,KAAK,CAAC,GAAG,EAAE;gBACV,WAAW;YACb,CAAC,CAAC,CAAC;YAEL,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,YAAY,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;YACzB,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC1B,MAAM,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YACzB,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { DataBus } from '@ms-cloudpack/data-bus';\nimport type { TRPCClient } from '@trpc/client';\nimport type { Unsubscribable } from '@trpc/server/observable';\nimport type { AppRouter } from '../types/AppRouter.js';\n\nexport function connectBusToClient(params: { bus: DataBus; client: TRPCClient<AppRouter> }): void {\n const { bus, client } = params;\n const subIds: Record<string, Unsubscribable> = {};\n\n bus.addProvider({\n path: [],\n onActivate: ({ path }) => {\n const id = path.join('/');\n\n const onData = (value: unknown) => {\n bus.publish(path, value);\n };\n\n client.getData\n .query({ path })\n .then(onData)\n .catch(() => {\n /* no-op */\n });\n\n subIds[id] = client.onDataChanged.subscribe({ path }, { onData });\n },\n onDeactivate: ({ path }) => {\n const id = path.join('/');\n subIds[id].unsubscribe();\n delete subIds[id];\n },\n });\n}\n"]}