@supalive/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/README.md +22 -0
  2. package/dist/src/client/caller_client.d.ts +42 -0
  3. package/dist/src/client/caller_client.d.ts.map +1 -0
  4. package/dist/src/client/caller_client.js +77 -0
  5. package/dist/src/client/caller_client.js.map +1 -0
  6. package/dist/src/client/client.d.ts +149 -0
  7. package/dist/src/client/client.d.ts.map +1 -0
  8. package/dist/src/client/client.js +308 -0
  9. package/dist/src/client/client.js.map +1 -0
  10. package/dist/src/client/index.d.ts +17 -0
  11. package/dist/src/client/index.d.ts.map +1 -0
  12. package/dist/src/client/index.js +19 -0
  13. package/dist/src/client/index.js.map +1 -0
  14. package/dist/src/client/sub_key.d.ts +20 -0
  15. package/dist/src/client/sub_key.d.ts.map +1 -0
  16. package/dist/src/client/sub_key.js +37 -0
  17. package/dist/src/client/sub_key.js.map +1 -0
  18. package/dist/src/client/ws_client_manager.d.ts +268 -0
  19. package/dist/src/client/ws_client_manager.d.ts.map +1 -0
  20. package/dist/src/client/ws_client_manager.js +1013 -0
  21. package/dist/src/client/ws_client_manager.js.map +1 -0
  22. package/dist/src/config.d.ts +117 -0
  23. package/dist/src/config.d.ts.map +1 -0
  24. package/dist/src/config.js +2 -0
  25. package/dist/src/config.js.map +1 -0
  26. package/dist/src/db/bytes.d.ts +4 -0
  27. package/dist/src/db/bytes.d.ts.map +1 -0
  28. package/dist/src/db/bytes.js +24 -0
  29. package/dist/src/db/bytes.js.map +1 -0
  30. package/dist/src/db/cache.d.ts +30 -0
  31. package/dist/src/db/cache.d.ts.map +1 -0
  32. package/dist/src/db/cache.js +153 -0
  33. package/dist/src/db/cache.js.map +1 -0
  34. package/dist/src/db/codec.d.ts +10 -0
  35. package/dist/src/db/codec.d.ts.map +1 -0
  36. package/dist/src/db/codec.js +73 -0
  37. package/dist/src/db/codec.js.map +1 -0
  38. package/dist/src/db/context.d.ts +28 -0
  39. package/dist/src/db/context.d.ts.map +1 -0
  40. package/dist/src/db/context.js +147 -0
  41. package/dist/src/db/context.js.map +1 -0
  42. package/dist/src/db/db.d.ts +154 -0
  43. package/dist/src/db/db.d.ts.map +1 -0
  44. package/dist/src/db/db.js +23 -0
  45. package/dist/src/db/db.js.map +1 -0
  46. package/dist/src/db/mysql.d.ts +120 -0
  47. package/dist/src/db/mysql.d.ts.map +1 -0
  48. package/dist/src/db/mysql.js +708 -0
  49. package/dist/src/db/mysql.js.map +1 -0
  50. package/dist/src/db/postgres.d.ts +116 -0
  51. package/dist/src/db/postgres.d.ts.map +1 -0
  52. package/dist/src/db/postgres.js +998 -0
  53. package/dist/src/db/postgres.js.map +1 -0
  54. package/dist/src/db/query.d.ts +174 -0
  55. package/dist/src/db/query.d.ts.map +1 -0
  56. package/dist/src/db/query.js +790 -0
  57. package/dist/src/db/query.js.map +1 -0
  58. package/dist/src/db/query_definition.d.ts +54 -0
  59. package/dist/src/db/query_definition.d.ts.map +1 -0
  60. package/dist/src/db/query_definition.js +47 -0
  61. package/dist/src/db/query_definition.js.map +1 -0
  62. package/dist/src/db/realtime_db.d.ts +19 -0
  63. package/dist/src/db/realtime_db.d.ts.map +1 -0
  64. package/dist/src/db/realtime_db.js +98 -0
  65. package/dist/src/db/realtime_db.js.map +1 -0
  66. package/dist/src/db/schema.d.ts +110 -0
  67. package/dist/src/db/schema.d.ts.map +1 -0
  68. package/dist/src/db/schema.js +47 -0
  69. package/dist/src/db/schema.js.map +1 -0
  70. package/dist/src/db/types_client_rpc.d.ts +157 -0
  71. package/dist/src/db/types_client_rpc.d.ts.map +1 -0
  72. package/dist/src/db/types_client_rpc.js +106 -0
  73. package/dist/src/db/types_client_rpc.js.map +1 -0
  74. package/dist/src/db/types_db.d.ts +236 -0
  75. package/dist/src/db/types_db.d.ts.map +1 -0
  76. package/dist/src/db/types_db.js +188 -0
  77. package/dist/src/db/types_db.js.map +1 -0
  78. package/dist/src/exports/mysql.d.ts +2 -0
  79. package/dist/src/exports/mysql.d.ts.map +1 -0
  80. package/dist/src/exports/mysql.js +2 -0
  81. package/dist/src/exports/mysql.js.map +1 -0
  82. package/dist/src/exports/postgres.d.ts +2 -0
  83. package/dist/src/exports/postgres.d.ts.map +1 -0
  84. package/dist/src/exports/postgres.js +2 -0
  85. package/dist/src/exports/postgres.js.map +1 -0
  86. package/dist/src/exports/procedure.d.ts +5 -0
  87. package/dist/src/exports/procedure.d.ts.map +1 -0
  88. package/dist/src/exports/procedure.js +5 -0
  89. package/dist/src/exports/procedure.js.map +1 -0
  90. package/dist/src/exports/server.d.ts +3 -0
  91. package/dist/src/exports/server.d.ts.map +1 -0
  92. package/dist/src/exports/server.js +3 -0
  93. package/dist/src/exports/server.js.map +1 -0
  94. package/dist/src/exports/types.d.ts +6 -0
  95. package/dist/src/exports/types.d.ts.map +1 -0
  96. package/dist/src/exports/types.js +6 -0
  97. package/dist/src/exports/types.js.map +1 -0
  98. package/dist/src/helper.d.ts +11 -0
  99. package/dist/src/helper.d.ts.map +1 -0
  100. package/dist/src/helper.js +45 -0
  101. package/dist/src/helper.js.map +1 -0
  102. package/dist/src/logger.d.ts +7 -0
  103. package/dist/src/logger.d.ts.map +1 -0
  104. package/dist/src/logger.js +45 -0
  105. package/dist/src/logger.js.map +1 -0
  106. package/dist/src/router/index.d.ts +4 -0
  107. package/dist/src/router/index.d.ts.map +1 -0
  108. package/dist/src/router/index.js +4 -0
  109. package/dist/src/router/index.js.map +1 -0
  110. package/dist/src/router/procedure.d.ts +204 -0
  111. package/dist/src/router/procedure.d.ts.map +1 -0
  112. package/dist/src/router/procedure.js +122 -0
  113. package/dist/src/router/procedure.js.map +1 -0
  114. package/dist/src/router/router.d.ts +88 -0
  115. package/dist/src/router/router.d.ts.map +1 -0
  116. package/dist/src/router/router.js +88 -0
  117. package/dist/src/router/router.js.map +1 -0
  118. package/dist/src/server/hash.d.ts +12 -0
  119. package/dist/src/server/hash.d.ts.map +1 -0
  120. package/dist/src/server/hash.js +20 -0
  121. package/dist/src/server/hash.js.map +1 -0
  122. package/dist/src/server/hash.test.d.ts +2 -0
  123. package/dist/src/server/hash.test.d.ts.map +1 -0
  124. package/dist/src/server/hash.test.js +43 -0
  125. package/dist/src/server/hash.test.js.map +1 -0
  126. package/dist/src/server/index.d.ts +8 -0
  127. package/dist/src/server/index.d.ts.map +1 -0
  128. package/dist/src/server/index.js +7 -0
  129. package/dist/src/server/index.js.map +1 -0
  130. package/dist/src/server/overlap-checker.d.ts +18 -0
  131. package/dist/src/server/overlap-checker.d.ts.map +1 -0
  132. package/dist/src/server/overlap-checker.js +247 -0
  133. package/dist/src/server/overlap-checker.js.map +1 -0
  134. package/dist/src/server/sub_hash.d.ts +23 -0
  135. package/dist/src/server/sub_hash.d.ts.map +1 -0
  136. package/dist/src/server/sub_hash.js +38 -0
  137. package/dist/src/server/sub_hash.js.map +1 -0
  138. package/dist/src/server/subscription-manager-client.d.ts +120 -0
  139. package/dist/src/server/subscription-manager-client.d.ts.map +1 -0
  140. package/dist/src/server/subscription-manager-client.js +207 -0
  141. package/dist/src/server/subscription-manager-client.js.map +1 -0
  142. package/dist/src/server/subscription-manager-types.d.ts +168 -0
  143. package/dist/src/server/subscription-manager-types.d.ts.map +1 -0
  144. package/dist/src/server/subscription-manager-types.js +94 -0
  145. package/dist/src/server/subscription-manager-types.js.map +1 -0
  146. package/dist/src/server/subscription-manager-worker-entry.d.ts +2 -0
  147. package/dist/src/server/subscription-manager-worker-entry.d.ts.map +1 -0
  148. package/dist/src/server/subscription-manager-worker-entry.js +127 -0
  149. package/dist/src/server/subscription-manager-worker-entry.js.map +1 -0
  150. package/dist/src/server/subscription-manager-worker-protocol.d.ts +40 -0
  151. package/dist/src/server/subscription-manager-worker-protocol.d.ts.map +1 -0
  152. package/dist/src/server/subscription-manager-worker-protocol.js +20 -0
  153. package/dist/src/server/subscription-manager-worker-protocol.js.map +1 -0
  154. package/dist/src/server/subscription-manager.d.ts +32 -0
  155. package/dist/src/server/subscription-manager.d.ts.map +1 -0
  156. package/dist/src/server/subscription-manager.js +249 -0
  157. package/dist/src/server/subscription-manager.js.map +1 -0
  158. package/dist/src/server/subscription-manager.test.d.ts +2 -0
  159. package/dist/src/server/subscription-manager.test.d.ts.map +1 -0
  160. package/dist/src/server/subscription-manager.test.js +610 -0
  161. package/dist/src/server/subscription-manager.test.js.map +1 -0
  162. package/dist/src/server/subscription-worker.d.ts +32 -0
  163. package/dist/src/server/subscription-worker.d.ts.map +1 -0
  164. package/dist/src/server/subscription-worker.js +190 -0
  165. package/dist/src/server/subscription-worker.js.map +1 -0
  166. package/dist/src/server/supalive-server.d.ts +158 -0
  167. package/dist/src/server/supalive-server.d.ts.map +1 -0
  168. package/dist/src/server/supalive-server.js +1048 -0
  169. package/dist/src/server/supalive-server.js.map +1 -0
  170. package/dist/src/server/types_server.d.ts +96 -0
  171. package/dist/src/server/types_server.d.ts.map +1 -0
  172. package/dist/src/server/types_server.js +36 -0
  173. package/dist/src/server/types_server.js.map +1 -0
  174. package/dist/tsconfig.tsbuildinfo +1 -0
  175. package/package.json +83 -0
@@ -0,0 +1,204 @@
1
+ import type { ZodType } from "zod";
2
+ import type { DbReader, DbWriter } from "../db/context";
3
+ import type { SupaliveDb } from "../db/realtime_db";
4
+ /**
5
+ * Query context passed to query handlers.
6
+ * Contains database reader and user-defined server context.
7
+ */
8
+ export interface QueryCtx<TContext = unknown> {
9
+ /** Database reader for queries */
10
+ db: DbReader;
11
+ /** User-defined server context (auth, requestId, etc.) */
12
+ serverCtx: TContext;
13
+ }
14
+ /**
15
+ * Mutation context passed to mutation handlers.
16
+ * Contains database writer and user-defined server context.
17
+ */
18
+ export interface MutationCtx<TContext = unknown> {
19
+ /** Database writer for mutations (includes insert/update/delete) */
20
+ db: DbWriter;
21
+ /** User-defined server context (auth, requestId, etc.) */
22
+ serverCtx: TContext;
23
+ }
24
+ /**
25
+ * Action context passed to action handlers.
26
+ * Contains the full SupaliveDb for both queries and mutations, plus user-defined server context.
27
+ */
28
+ export interface ActionCtx<TContext = unknown> {
29
+ /** Full database interface for queries and mutations */
30
+ db: SupaliveDb;
31
+ /** User-defined server context (auth, requestId, etc.) */
32
+ serverCtx: TContext;
33
+ }
34
+ export type QueryFn<TInput, TResult, TContext = unknown> = (ctx: QueryCtx<TContext>, input: TInput) => Promise<TResult>;
35
+ export type MutationFn<TInput, TResult, TContext = unknown> = (ctx: MutationCtx<TContext>, input: TInput) => Promise<TResult>;
36
+ export type ActionFn<TInput, TResult, TContext = unknown> = (ctx: ActionCtx<TContext>, input: TInput) => Promise<TResult>;
37
+ /**
38
+ * Per-procedure override for the cache/subscription segmentation key.
39
+ *
40
+ * omitted | undefined → fall back to `config.getUserId(serverCtx)` (default)
41
+ * false → no identity in hash; cache/sub shared across all users
42
+ * string → a static identity literal (e.g. "public" or a tenant id)
43
+ * function → compute from serverCtx + input (sync)
44
+ *
45
+ * When the result of a query is identical regardless of who calls it, set
46
+ * this to a literal (or `false`) so a single cache entry serves everyone.
47
+ *
48
+ * The function form intentionally takes `serverCtx` (not the full `QueryCtx`)
49
+ * because identity is resolved before any DB read is issued.
50
+ */
51
+ export type QueryIdentitySpec<TInput, TContext> = false | string | ((serverCtx: TContext, input: TInput) => string | null | undefined);
52
+ export interface BaseProcedure<TInput, TResult, TType extends "query" | "mutation" | "action", TContext = unknown, TInternal extends boolean = boolean> {
53
+ readonly _type: "procedure";
54
+ readonly procedureType: TType;
55
+ readonly inputSchema: ZodType<TInput>;
56
+ readonly fn: QueryFn<TInput, TResult, TContext> | MutationFn<TInput, TResult, TContext> | ActionFn<TInput, TResult, TContext>;
57
+ readonly internal: TInternal;
58
+ }
59
+ export interface QueryProcedure<TInput, TResult, TContext = unknown, TInternal extends boolean = boolean> extends BaseProcedure<TInput, TResult, "query", TContext, TInternal> {
60
+ readonly procedureType: "query";
61
+ readonly fn: QueryFn<TInput, TResult, TContext>;
62
+ readonly queryIdentity?: QueryIdentitySpec<TInput, TContext>;
63
+ }
64
+ export interface MutationProcedure<TInput, TResult, TContext = unknown, TInternal extends boolean = boolean> extends BaseProcedure<TInput, TResult, "mutation", TContext, TInternal> {
65
+ readonly procedureType: "mutation";
66
+ readonly fn: MutationFn<TInput, TResult, TContext>;
67
+ }
68
+ export interface ActionProcedure<TInput, TResult, TContext = unknown, TInternal extends boolean = boolean> extends BaseProcedure<TInput, TResult, "action", TContext, TInternal> {
69
+ readonly procedureType: "action";
70
+ readonly fn: ActionFn<TInput, TResult, TContext>;
71
+ }
72
+ export type AnyProcedure<TContext = unknown> = QueryProcedure<any, any, TContext> | MutationProcedure<any, any, TContext> | ActionProcedure<any, any, TContext>;
73
+ export interface QueryConfig<TInput, TResult, TContext = unknown> {
74
+ /** Zod schema for input validation */
75
+ args: ZodType<TInput>;
76
+ /** The query handler function */
77
+ handler: QueryFn<TInput, TResult, TContext>;
78
+ /** Mark as internal (server-only). Default: false */
79
+ internal?: boolean;
80
+ /**
81
+ * Override the cache/subscription segmentation key for this procedure.
82
+ * See {@link QueryIdentitySpec}. Omit to keep the default (per-user) behavior.
83
+ */
84
+ queryIdentity?: QueryIdentitySpec<TInput, TContext>;
85
+ }
86
+ export interface MutationConfig<TInput, TResult, TContext = unknown> {
87
+ /** Zod schema for input validation */
88
+ args: ZodType<TInput>;
89
+ /** The mutation handler function */
90
+ handler: MutationFn<TInput, TResult, TContext>;
91
+ /** Mark as internal (server-only). Default: false */
92
+ internal?: boolean;
93
+ }
94
+ export interface ActionConfig<TInput, TResult, TContext = unknown> {
95
+ /** Zod schema for input validation */
96
+ args: ZodType<TInput>;
97
+ /** The action handler function */
98
+ handler: ActionFn<TInput, TResult, TContext>;
99
+ /** Mark as internal (server-only). Default: false */
100
+ internal?: boolean;
101
+ }
102
+ /** Extract input type from a procedure */
103
+ export type InputOf<T> = T extends BaseProcedure<infer I, any, any, any> ? I : never;
104
+ /** Extract output type from a procedure */
105
+ export type OutputOf<T> = T extends BaseProcedure<any, infer O, any, any> ? O : never;
106
+ /** Extract procedure type (query/mutation) */
107
+ export type TypeOf<T> = T extends BaseProcedure<any, any, infer Type, any> ? Type : never;
108
+ /** Extract server context type from a procedure */
109
+ export type ContextOf<T> = T extends BaseProcedure<any, any, any, infer C> ? C : never;
110
+ /**
111
+ * Create a query builder with a pre-defined context type.
112
+ * This allows you to define the context type once and have it inferred
113
+ * automatically in all your query handlers.
114
+ *
115
+ * @example
116
+ * // Define your server context
117
+ * interface ServerContext {
118
+ * auth: { userId: string };
119
+ * requestId: string;
120
+ * }
121
+ *
122
+ * // Create a typed query builder
123
+ * const query = createQueryBuilder<ServerContext>();
124
+ *
125
+ * // Use it - context type is automatically inferred!
126
+ * const getUser = query({
127
+ * args: z.object({ id: z.string() }),
128
+ * handler: async (ctx, { id }) => {
129
+ * // ctx.db for database queries
130
+ * const user = await ctx.db.query(UsersSchema).find(id);
131
+ * // ctx.context for server context
132
+ * console.log(ctx.context.requestId);
133
+ * return user;
134
+ * }
135
+ * });
136
+ */
137
+ export declare function createQueryBuilder<TContext = unknown>(): <TInput, TResult, const TInternal extends boolean = false>(config: QueryConfig<TInput, TResult, TContext> & {
138
+ internal?: TInternal;
139
+ }) => QueryProcedure<TInput, TResult, TContext, TInternal>;
140
+ /**
141
+ * Create a mutation builder with a pre-defined context type.
142
+ * This allows you to define the context type once and have it inferred
143
+ * automatically in all your mutation handlers.
144
+ *
145
+ * @example
146
+ * // Define your server context
147
+ * interface ServerContext {
148
+ * auth: { userId: string };
149
+ * requestId: string;
150
+ * }
151
+ *
152
+ * // Create a typed mutation builder
153
+ * const mutation = createMutationBuilder<ServerContext>();
154
+ *
155
+ * // Use it - context type is automatically inferred!
156
+ * const createUser = mutation({
157
+ * args: z.object({ name: z.string() }),
158
+ * handler: async (ctx, { name }) => {
159
+ * // ctx.db for mutations
160
+ * await ctx.db.insert(UsersSchema, id, { name });
161
+ * // ctx.context for server context
162
+ * console.log(ctx.context.requestId);
163
+ * return { success: true };
164
+ * }
165
+ * });
166
+ */
167
+ export declare function createMutationBuilder<TContext = unknown>(): <TInput, TResult, const TInternal extends boolean = false>(config: MutationConfig<TInput, TResult, TContext> & {
168
+ internal?: TInternal;
169
+ }) => MutationProcedure<TInput, TResult, TContext, TInternal>;
170
+ /**
171
+ * Create an action builder with a pre-defined context type.
172
+ * Actions have access to the full SupaliveDb for both queries and mutations.
173
+ *
174
+ * @example
175
+ * // Define your server context
176
+ * interface ServerContext {
177
+ * auth: { userId: string };
178
+ * requestId: string;
179
+ * }
180
+ *
181
+ * // Create a typed action builder
182
+ * const action = createActionBuilder<ServerContext>();
183
+ *
184
+ * // Use it - context type is automatically inferred!
185
+ * const processOrder = action({
186
+ * args: z.object({ orderId: z.string() }),
187
+ * handler: async (ctx, { orderId }) => {
188
+ * // ctx.db for full database access
189
+ * const order = await ctx.db.query(async (db) => {
190
+ * return db.query(OrdersSchema).find(orderId);
191
+ * });
192
+ * await ctx.db.mutation(async (db) => {
193
+ * await db.update(OrdersSchema, orderId, { status: "processed" });
194
+ * });
195
+ * // ctx.context for server context
196
+ * console.log(ctx.context.requestId);
197
+ * return { success: true };
198
+ * }
199
+ * });
200
+ */
201
+ export declare function createActionBuilder<TContext = unknown>(): <TInput, TResult, const TInternal extends boolean = false>(config: ActionConfig<TInput, TResult, TContext> & {
202
+ internal?: TInternal;
203
+ }) => ActionProcedure<TInput, TResult, TContext, TInternal>;
204
+ //# sourceMappingURL=procedure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"procedure.d.ts","sourceRoot":"","sources":["../../../src/router/procedure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Create a query builder with a pre-defined context type.
3
+ * This allows you to define the context type once and have it inferred
4
+ * automatically in all your query handlers.
5
+ *
6
+ * @example
7
+ * // Define your server context
8
+ * interface ServerContext {
9
+ * auth: { userId: string };
10
+ * requestId: string;
11
+ * }
12
+ *
13
+ * // Create a typed query builder
14
+ * const query = createQueryBuilder<ServerContext>();
15
+ *
16
+ * // Use it - context type is automatically inferred!
17
+ * const getUser = query({
18
+ * args: z.object({ id: z.string() }),
19
+ * handler: async (ctx, { id }) => {
20
+ * // ctx.db for database queries
21
+ * const user = await ctx.db.query(UsersSchema).find(id);
22
+ * // ctx.context for server context
23
+ * console.log(ctx.context.requestId);
24
+ * return user;
25
+ * }
26
+ * });
27
+ */
28
+ export function createQueryBuilder() {
29
+ return function query(config) {
30
+ return {
31
+ _type: "procedure",
32
+ procedureType: "query",
33
+ inputSchema: config.args,
34
+ fn: config.handler,
35
+ internal: (config.internal ?? false),
36
+ queryIdentity: config.queryIdentity,
37
+ };
38
+ };
39
+ }
40
+ // ─── Mutation Builder Factory ────────────────────────────────────────────────
41
+ /**
42
+ * Create a mutation builder with a pre-defined context type.
43
+ * This allows you to define the context type once and have it inferred
44
+ * automatically in all your mutation handlers.
45
+ *
46
+ * @example
47
+ * // Define your server context
48
+ * interface ServerContext {
49
+ * auth: { userId: string };
50
+ * requestId: string;
51
+ * }
52
+ *
53
+ * // Create a typed mutation builder
54
+ * const mutation = createMutationBuilder<ServerContext>();
55
+ *
56
+ * // Use it - context type is automatically inferred!
57
+ * const createUser = mutation({
58
+ * args: z.object({ name: z.string() }),
59
+ * handler: async (ctx, { name }) => {
60
+ * // ctx.db for mutations
61
+ * await ctx.db.insert(UsersSchema, id, { name });
62
+ * // ctx.context for server context
63
+ * console.log(ctx.context.requestId);
64
+ * return { success: true };
65
+ * }
66
+ * });
67
+ */
68
+ export function createMutationBuilder() {
69
+ return function mutation(config) {
70
+ return {
71
+ _type: "procedure",
72
+ procedureType: "mutation",
73
+ inputSchema: config.args,
74
+ fn: config.handler,
75
+ internal: (config.internal ?? false),
76
+ };
77
+ };
78
+ }
79
+ // ─── Action Builder Factory ──────────────────────────────────────────────────
80
+ /**
81
+ * Create an action builder with a pre-defined context type.
82
+ * Actions have access to the full SupaliveDb for both queries and mutations.
83
+ *
84
+ * @example
85
+ * // Define your server context
86
+ * interface ServerContext {
87
+ * auth: { userId: string };
88
+ * requestId: string;
89
+ * }
90
+ *
91
+ * // Create a typed action builder
92
+ * const action = createActionBuilder<ServerContext>();
93
+ *
94
+ * // Use it - context type is automatically inferred!
95
+ * const processOrder = action({
96
+ * args: z.object({ orderId: z.string() }),
97
+ * handler: async (ctx, { orderId }) => {
98
+ * // ctx.db for full database access
99
+ * const order = await ctx.db.query(async (db) => {
100
+ * return db.query(OrdersSchema).find(orderId);
101
+ * });
102
+ * await ctx.db.mutation(async (db) => {
103
+ * await db.update(OrdersSchema, orderId, { status: "processed" });
104
+ * });
105
+ * // ctx.context for server context
106
+ * console.log(ctx.context.requestId);
107
+ * return { success: true };
108
+ * }
109
+ * });
110
+ */
111
+ export function createActionBuilder() {
112
+ return function action(config) {
113
+ return {
114
+ _type: "procedure",
115
+ procedureType: "action",
116
+ inputSchema: config.args,
117
+ fn: config.handler,
118
+ internal: (config.internal ?? false),
119
+ };
120
+ };
121
+ }
122
+ //# sourceMappingURL=procedure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"procedure.js","sourceRoot":"","sources":["../../../src/router/procedure.ts"],"names":[],"mappings":"AAuKA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,SAAS,KAAK,CACnB,MAAyE;QAEzE,OAAO;YACL,KAAK,EAAE,WAAW;YAClB,aAAa,EAAE,OAAO;YACtB,WAAW,EAAE,MAAM,CAAC,IAAI;YACxB,EAAE,EAAE,MAAM,CAAC,OAAO;YAClB,QAAQ,EAAE,CAAC,MAAM,CAAC,QAAQ,IAAI,KAAK,CAAc;YACjD,aAAa,EAAE,MAAM,CAAC,aAAa;SACpC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,SAAS,QAAQ,CACtB,MAA4E;QAE5E,OAAO;YACL,KAAK,EAAE,WAAW;YAClB,aAAa,EAAE,UAAU;YACzB,WAAW,EAAE,MAAM,CAAC,IAAI;YACxB,EAAE,EAAE,MAAM,CAAC,OAAO;YAClB,QAAQ,EAAE,CAAC,MAAM,CAAC,QAAQ,IAAI,KAAK,CAAc;SAClD,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,SAAS,MAAM,CACpB,MAA0E;QAE1E,OAAO;YACL,KAAK,EAAE,WAAW;YAClB,aAAa,EAAE,QAAQ;YACvB,WAAW,EAAE,MAAM,CAAC,IAAI;YACxB,EAAE,EAAE,MAAM,CAAC,OAAO;YAClB,QAAQ,EAAE,CAAC,MAAM,CAAC,QAAQ,IAAI,KAAK,CAAc;SAClD,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,88 @@
1
+ import type { AnyProcedure } from "./procedure";
2
+ /**
3
+ * A router maps procedure names (keys) to their definitions.
4
+ * This is the type that's exported from your app and used by the client.
5
+ */
6
+ export type Router<TProcedures extends Record<string, AnyProcedure<TContext>>, TContext = unknown> = {
7
+ _type: "router";
8
+ procedures: TProcedures;
9
+ contextName: string;
10
+ };
11
+ /**
12
+ * Inferred AppRouter type from router() call.
13
+ * Captures the full procedure map for client type inference.
14
+ */
15
+ export type AppRouter<TProcedures extends Record<string, AnyProcedure<TContext>> = Record<string, AnyProcedure>, TContext = unknown> = Router<TProcedures, TContext>;
16
+ /** Get query procedures only from a router */
17
+ export type QueryProcedures<T extends Record<string, AnyProcedure>> = {
18
+ [K in keyof T as T[K] extends {
19
+ procedureType: "query";
20
+ } ? K : never]: T[K];
21
+ };
22
+ /** Get mutation procedures only from a router */
23
+ export type MutationProcedures<T extends Record<string, AnyProcedure>> = {
24
+ [K in keyof T as T[K] extends {
25
+ procedureType: "mutation";
26
+ } ? K : never]: T[K];
27
+ };
28
+ /** Get action procedures only from a router */
29
+ export type ActionProcedures<T extends Record<string, AnyProcedure>> = {
30
+ [K in keyof T as T[K] extends {
31
+ procedureType: "action";
32
+ } ? K : never]: T[K];
33
+ };
34
+ /** Get public (non-internal) procedures - for client type safety */
35
+ export type PublicProcedures<T extends Record<string, AnyProcedure>> = Pick<T, {
36
+ [K in keyof T]: T[K] extends {
37
+ internal: true;
38
+ } ? never : K;
39
+ }[keyof T]>;
40
+ /** Extract procedure names from a router */
41
+ export type ProcedureNames<T extends Router<any>> = T extends Router<infer P> ? keyof P : never;
42
+ export type RouterConfig<T> = {
43
+ procedures: T;
44
+ contextName?: string;
45
+ };
46
+ /**
47
+ * Create a router from procedure definitions.
48
+ * Procedure names are inferred from the object keys.
49
+ *
50
+ * @example
51
+ * const appRouter = router({
52
+ * procedures: {
53
+ * getUser,
54
+ * createUser,
55
+ * internalGetAll,
56
+ * },
57
+ * });
58
+ *
59
+ * export type AppRouter = typeof appRouter;
60
+ */
61
+ export declare function router<TProcedures extends Record<string, AnyProcedure<any>>, TContext = unknown>(config: RouterConfig<TProcedures>): Router<TProcedures, TContext>;
62
+ export interface RegisteredProcedure<TContext = unknown> {
63
+ name: string;
64
+ type: "query" | "mutation" | "action";
65
+ internal: boolean;
66
+ inputSchema: AnyProcedure<TContext>["inputSchema"];
67
+ fn: AnyProcedure<TContext>["fn"];
68
+ /** Only present for `type === "query"`. See `QueryIdentitySpec`. */
69
+ queryIdentity?: false | string | ((serverCtx: TContext, input: unknown) => string | null | undefined);
70
+ }
71
+ export declare function getContextRegistry(inContext: string): ContextRegistry;
72
+ export declare class ContextRegistry {
73
+ procedureRegistry: Map<string, RegisteredProcedure<any>>;
74
+ internalProcedureNames: Set<string>;
75
+ registerProcedure<TContext>(name: string, proc: AnyProcedure<TContext>): void;
76
+ /** Get a registered procedure by name (runtime lookup) */
77
+ getProcedure<TContext = unknown>(name: string): RegisteredProcedure<TContext> | undefined;
78
+ /** Get all registered procedure names */
79
+ getProcedureNames(): string[];
80
+ /** Get all registered procedures */
81
+ getAllProcedures(): Map<string, RegisteredProcedure>;
82
+ /** Clear the registry (for testing only) */
83
+ clearRegistry(): void;
84
+ markInternalProcedure(name: string): void;
85
+ isInternalProcedure(name: string): boolean;
86
+ clearInternalProcedures(): void;
87
+ }
88
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/router/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Create a router from procedure definitions.
3
+ * Procedure names are inferred from the object keys.
4
+ *
5
+ * @example
6
+ * const appRouter = router({
7
+ * procedures: {
8
+ * getUser,
9
+ * createUser,
10
+ * internalGetAll,
11
+ * },
12
+ * });
13
+ *
14
+ * export type AppRouter = typeof appRouter;
15
+ */
16
+ export function router(config) {
17
+ const registry = getContextRegistry(config.contextName ?? "default");
18
+ // Register all procedures at router creation time
19
+ for (const [name, proc] of Object.entries(config.procedures)) {
20
+ registry.registerProcedure(name, proc);
21
+ }
22
+ return {
23
+ _type: "router",
24
+ procedures: config.procedures,
25
+ contextName: config.contextName ?? "default",
26
+ };
27
+ }
28
+ const contextRegistry = new Map();
29
+ export function getContextRegistry(inContext) {
30
+ let registry = contextRegistry.get(inContext);
31
+ if (!registry) {
32
+ registry = new ContextRegistry();
33
+ contextRegistry.set(inContext, registry);
34
+ }
35
+ return registry;
36
+ }
37
+ export class ContextRegistry {
38
+ procedureRegistry = new Map();
39
+ internalProcedureNames = new Set();
40
+ registerProcedure(name, proc) {
41
+ if (this.procedureRegistry.has(name)) {
42
+ throw new Error(`[router] Procedure "${name}" is already registered. ` +
43
+ `Each procedure name must be unique across the application.`);
44
+ }
45
+ // Track internal procedures by name
46
+ if (proc.internal) {
47
+ this.markInternalProcedure(name);
48
+ }
49
+ const queryIdentity = proc.procedureType === "query"
50
+ ? proc.queryIdentity
51
+ : undefined;
52
+ this.procedureRegistry.set(name, {
53
+ name,
54
+ type: proc.procedureType,
55
+ internal: proc.internal,
56
+ inputSchema: proc.inputSchema,
57
+ fn: proc.fn,
58
+ queryIdentity,
59
+ });
60
+ }
61
+ /** Get a registered procedure by name (runtime lookup) */
62
+ getProcedure(name) {
63
+ return this.procedureRegistry.get(name);
64
+ }
65
+ /** Get all registered procedure names */
66
+ getProcedureNames() {
67
+ return [...this.procedureRegistry.keys()];
68
+ }
69
+ /** Get all registered procedures */
70
+ getAllProcedures() {
71
+ return new Map(this.procedureRegistry);
72
+ }
73
+ /** Clear the registry (for testing only) */
74
+ clearRegistry() {
75
+ this.procedureRegistry.clear();
76
+ this.clearInternalProcedures();
77
+ }
78
+ markInternalProcedure(name) {
79
+ this.internalProcedureNames.add(name);
80
+ }
81
+ isInternalProcedure(name) {
82
+ return this.internalProcedureNames.has(name);
83
+ }
84
+ clearInternalProcedures() {
85
+ this.internalProcedureNames.clear();
86
+ }
87
+ }
88
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../src/router/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * FNV-1a 32-bit hash.
3
+ *
4
+ * Used for routing subscription operations to logical workers inside the
5
+ * sub-manager process. Same input always returns the same 32-bit unsigned
6
+ * integer in both JavaScript and Go, so a future Go port of the sub-manager
7
+ * can use the identical routing without rebalancing keys.
8
+ *
9
+ * Reference: http://www.isthe.com/chongo/tech/comp/fnv/
10
+ */
11
+ export declare function fnv1a32(s: string): number;
12
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../../src/server/hash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAQzC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * FNV-1a 32-bit hash.
3
+ *
4
+ * Used for routing subscription operations to logical workers inside the
5
+ * sub-manager process. Same input always returns the same 32-bit unsigned
6
+ * integer in both JavaScript and Go, so a future Go port of the sub-manager
7
+ * can use the identical routing without rebalancing keys.
8
+ *
9
+ * Reference: http://www.isthe.com/chongo/tech/comp/fnv/
10
+ */
11
+ export function fnv1a32(s) {
12
+ let h = 0x811c9dc5;
13
+ for (let i = 0; i < s.length; i++) {
14
+ h ^= s.charCodeAt(i);
15
+ // h = h * 16777619, expressed as shifts to stay in 32-bit space
16
+ h = (h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24))) >>> 0;
17
+ }
18
+ return h >>> 0;
19
+ }
20
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../../src/server/hash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,UAAU,OAAO,CAAC,CAAS;IAC/B,IAAI,CAAC,GAAG,UAAU,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACrB,gEAAgE;QAChE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=hash.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.test.d.ts","sourceRoot":"","sources":["../../../src/server/hash.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,43 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { fnv1a32 } from "./hash";
3
+ describe("fnv1a32", () => {
4
+ it("is deterministic", () => {
5
+ expect(fnv1a32("hello")).toBe(fnv1a32("hello"));
6
+ expect(fnv1a32("")).toBe(fnv1a32(""));
7
+ });
8
+ it("returns a 32-bit unsigned integer", () => {
9
+ const samples = ["", "a", "hello world", "sub_abc123", "x".repeat(200)];
10
+ for (const s of samples) {
11
+ const h = fnv1a32(s);
12
+ expect(Number.isInteger(h)).toBe(true);
13
+ expect(h >= 0).toBe(true);
14
+ expect(h <= 0xffffffff).toBe(true);
15
+ }
16
+ });
17
+ it("matches well-known FNV-1a 32 reference vectors", () => {
18
+ // Reference values from the canonical FNV-1a 32-bit specification.
19
+ // http://www.isthe.com/chongo/tech/comp/fnv/
20
+ expect(fnv1a32("")).toBe(0x811c9dc5);
21
+ expect(fnv1a32("a")).toBe(0xe40c292c);
22
+ expect(fnv1a32("foobar")).toBe(0xbf9cf968);
23
+ });
24
+ it("differs for different inputs", () => {
25
+ expect(fnv1a32("a")).not.toBe(fnv1a32("b"));
26
+ expect(fnv1a32("hello")).not.toBe(fnv1a32("Hello"));
27
+ });
28
+ it("distributes reasonably evenly across small buckets", () => {
29
+ const buckets = new Array(4).fill(0);
30
+ const N = 2000;
31
+ for (let i = 0; i < N; i++) {
32
+ buckets[fnv1a32(`sub_${i}`) % 4]++;
33
+ }
34
+ // Each bucket should be within ~25% of the expected mean (N/4 = 500).
35
+ // We allow a generous band because this is a sanity check, not a
36
+ // distribution proof.
37
+ for (const c of buckets) {
38
+ expect(c).toBeGreaterThan(N / 4 * 0.75);
39
+ expect(c).toBeLessThan(N / 4 * 1.25);
40
+ }
41
+ });
42
+ });
43
+ //# sourceMappingURL=hash.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.test.js","sourceRoot":"","sources":["../../../src/server/hash.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEjC,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAC1B,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,OAAO,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACxE,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YACrB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,MAAM,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,mEAAmE;QACnE,6CAA6C;QAC7C,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,OAAO,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAa,CAAC;QACjD,MAAM,CAAC,GAAG,IAAI,CAAC;QACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAE,EAAE,CAAC;QACtC,CAAC;QACD,sEAAsE;QACtE,iEAAiE;QACjE,sBAAsB;QACtB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;YACxC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QACvC,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { SupaliveWebSocketServer } from "./supalive-server";
2
+ export { SubscriptionManager } from "./subscription-manager";
3
+ export { SubManagerClient } from "./subscription-manager-client";
4
+ export { RegisterSubscriptionParamsSchema, type RegisterSubscriptionParams, type RegisterSubscriptionResult, UpdateSubscriptionReadSetParamsSchema, type UpdateSubscriptionReadSetParams, type UpdateSubscriptionReadSetResult, UnregisterSubscriptionParamsSchema, type UnregisterSubscriptionParams, type UnregisterSubscriptionResult, InvalidateWritesetParamsSchema, type InvalidateWritesetParams, type InvalidateWritesetResult, type AffectedSubscription, } from "./subscription-manager-types";
5
+ export { CacheLayer } from "../db/cache";
6
+ export { generateSubscriptionId, generateCacheKey, getHashOf, ANONYMOUS_IDENTITY, } from "./sub_hash";
7
+ export type { SubId } from "./types_server";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EACL,gCAAgC,EAChC,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,EAC/B,qCAAqC,EACrC,KAAK,+BAA+B,EACpC,KAAK,+BAA+B,EACpC,kCAAkC,EAClC,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,EACjC,8BAA8B,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,GAC1B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,SAAS,EACT,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { SupaliveWebSocketServer } from "./supalive-server";
2
+ export { SubscriptionManager } from "./subscription-manager";
3
+ export { SubManagerClient } from "./subscription-manager-client";
4
+ export { RegisterSubscriptionParamsSchema, UpdateSubscriptionReadSetParamsSchema, UnregisterSubscriptionParamsSchema, InvalidateWritesetParamsSchema, } from "./subscription-manager-types";
5
+ export { CacheLayer } from "../db/cache";
6
+ export { generateSubscriptionId, generateCacheKey, getHashOf, ANONYMOUS_IDENTITY, } from "./sub_hash";
7
+ //# sourceMappingURL=index.js.map