zynapse 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.
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # zynapse
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,51 @@
1
+ import path from "path";
2
+ import { parseArgs } from "util";
3
+ import { GenerateCode } from "../schema/client_side";
4
+ import { readdirSync, rm } from "fs";
5
+ const { values: { inputFile, outputFolder }, } = parseArgs({
6
+ args: Bun.argv || process.argv,
7
+ allowPositionals: true,
8
+ options: {
9
+ inputFile: {
10
+ type: "string",
11
+ short: "I",
12
+ },
13
+ outputFolder: {
14
+ type: "string",
15
+ short: "O",
16
+ },
17
+ },
18
+ });
19
+ if (!inputFile || !outputFolder) {
20
+ throw new Error("One or more arguments are missing");
21
+ }
22
+ console.log("Code gen started", process.cwd());
23
+ // Find the file and dynamically import it
24
+ const fullPath = path.join(process.cwd(), inputFile);
25
+ const file = (await import(fullPath)).default;
26
+ // Remove old files.
27
+ const oldFilesDirectory = path.join(process.cwd(), outputFolder);
28
+ const files = readdirSync(oldFilesDirectory);
29
+ for (const file of files) {
30
+ const toDelete = path.join(oldFilesDirectory, file);
31
+ rm(toDelete, (err) => {
32
+ if (err) {
33
+ console.log(`Error con deleting file ${file}, ${err}`);
34
+ }
35
+ else {
36
+ console.log("Successfully deleted", file);
37
+ }
38
+ });
39
+ }
40
+ // TODO: Add some sort of validation to make sure the mentioned file is actually a schema
41
+ const services_buffers = await GenerateCode(file);
42
+ let total_bytes = 0;
43
+ for (const service_buf of services_buffers) {
44
+ const full_filename = path.join(process.cwd(), outputFolder, service_buf.filename);
45
+ const fHandle = Bun.file(full_filename);
46
+ const bytes = await fHandle.write(service_buf.code);
47
+ console.log(`${bytes} written to ${full_filename}`);
48
+ total_bytes += bytes;
49
+ }
50
+ console.log(`${total_bytes} total bytes written`);
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAEA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAiC,WAAW,EAAE,EAAE,EAAE,MAAM,IAAI,CAAC;AAEpE,MAAM,EACL,MAAM,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,GACnC,GAAG,SAAS,CAAC;IACb,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI;IAC9B,gBAAgB,EAAE,IAAI;IACtB,OAAO,EAAE;QACR,SAAS,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,GAAG;SACV;QACD,YAAY,EAAE;YACb,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,GAAG;SACV;KACD;CACD,CAAC,CAAC;AAEH,IAAI,CAAC,SAAS,IAAI,CAAC,YAAY,EAAE,CAAC;IACjC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;AACtD,CAAC;AAED,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAC/C,0CAA0C;AAE1C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;AACrD,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;AAE9C,oBAAoB;AACpB,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;AACjE,MAAM,KAAK,GAAG,WAAW,CAAC,iBAAiB,CAAC,CAAC;AAC7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;IAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;IACpD,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC;QACrB,IAAI,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;QACxD,CAAC;aAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;QAC3C,CAAC;IAAA,CACD,CAAC,CAAC;AACJ,CAAC;AAED,yFAAyF;AAEzF,MAAM,gBAAgB,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;AAElD,IAAI,WAAW,GAAG,CAAC,CAAC;AACpB,KAAK,MAAM,WAAW,IAAI,gBAAgB,EAAE,CAAC;IAC5C,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAC9B,OAAO,CAAC,GAAG,EAAE,EACb,YAAY,EACZ,WAAW,CAAC,QAAQ,CACpB,CAAC;IACF,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAExC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,eAAe,aAAa,EAAE,CAAC,CAAC;IACpD,WAAW,IAAI,KAAK,CAAC;AACtB,CAAC;AAED,OAAO,CAAC,GAAG,CAAC,GAAG,WAAW,sBAAsB,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { APISchema } from ".";
2
+ type ServiceCode = {
3
+ filename: string;
4
+ code: string;
5
+ };
6
+ type SchemaCodes = Array<ServiceCode>;
7
+ export declare function GenerateCode(schema: APISchema): Promise<SchemaCodes>;
8
+ export {};
9
+ //# sourceMappingURL=client_side.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client_side.d.ts","sourceRoot":"","sources":["../../src/schema/client_side.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAW,MAAM,GAAG,CAAC;AAgUvC,KAAK,WAAW,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAWtD,KAAK,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;AAEtC,wBAAsB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAwB1E"}
@@ -0,0 +1,308 @@
1
+ import { zodToTs, printNode, createTypeAlias } from "zod-to-ts";
2
+ import * as prettier from "prettier";
3
+ import ztj from "zod-to-json-schema";
4
+ import jtz from "json-schema-to-zod";
5
+ const buffer = `
6
+ import * as React from "react"
7
+ import {
8
+ useQuery,
9
+ useMutation,
10
+
11
+ } from "@tanstack/react-query";\n\n
12
+ `;
13
+ function getOutputAlias(proc, parentService) {
14
+ const outputTypeIdentifier = `${parentService.name}${proc.name}OutputType`;
15
+ const { node } = zodToTs(proc.output, outputTypeIdentifier);
16
+ const alias = createTypeAlias(node, outputTypeIdentifier);
17
+ const stringifiedAlias = printNode(alias);
18
+ return { outputTypeIdentifier, stringifiedAlias };
19
+ }
20
+ async function mutationProcedureCodeGen(proc, parentService) {
21
+ const { outputTypeIdentifier, stringifiedAlias } = getOutputAlias(proc, parentService);
22
+ const inputAliasIdentifier = `${parentService.name}${proc.name}InputSchema`;
23
+ const schema = ztj(proc.input, {
24
+ errorMessages: true,
25
+ markdownDescription: true,
26
+ });
27
+ // @ts-ignore
28
+ const zodCode = jtz(schema, {
29
+ withJsdocs: true,
30
+ name: inputAliasIdentifier,
31
+ });
32
+ let buff = `export ${stringifiedAlias}\nexport ${zodCode}\nexport function use${parentService.name}${proc.name}Mutation`;
33
+ buff += `(extraOptions?: Omit<UseMutationOptions<${outputTypeIdentifier}, Error, z.infer<typeof ${inputAliasIdentifier}>, unknown>, "mutationFn">) {
34
+ /*${proc.description}*/
35
+ return useMutation({
36
+ ...extraOptions,
37
+ mutationFn: async (args: z.infer<typeof ${inputAliasIdentifier}>) => {
38
+ const validationResult = await ${inputAliasIdentifier}.safeParseAsync(args)
39
+ if (validationResult.error) {
40
+ console.error("Error on validating mutation input ", validationResult.error)
41
+ throw new Error(validationResult.error.message)
42
+ }
43
+
44
+
45
+ const response = await fetch("/_api",{
46
+ method: "POST",
47
+ body: JSON.stringify({
48
+ service: '${parentService.name}',
49
+ procedure: '${proc.name}',
50
+ data: validationResult.data
51
+ }),
52
+ })
53
+
54
+ if (!response.ok) {
55
+ let backendErrorMessage = ""
56
+ try {
57
+ backendErrorMessage = await response.text()
58
+ } catch {
59
+ backendErrorMessage = "No Error message returned from backen"
60
+ }
61
+ throw new Error("Mutation: ${proc.name} Non ok response: " + backendErrorMessage)
62
+ }
63
+
64
+
65
+ const rawResponse = await response.json()
66
+
67
+ return rawResponse["data"] as ${outputTypeIdentifier}
68
+ }
69
+ })
70
+
71
+ }`;
72
+ return await prettier.format(buff, { parser: "babel-ts" });
73
+ }
74
+ async function subscriptionProcedureCodeGen(proc, parentService) {
75
+ const { outputTypeIdentifier, stringifiedAlias } = getOutputAlias(proc, parentService);
76
+ const inputIdentifier = `${parentService.name}${proc.name}SubscriptionInputSchema`;
77
+ const jsonSchema = ztj(proc.input, {
78
+ errorMessages: true,
79
+ markdownDescription: true,
80
+ });
81
+ // @ts-ignore
82
+ const schema = jtz(jsonSchema, {
83
+ withJsdocs: true,
84
+ name: inputIdentifier,
85
+ });
86
+ let buff = `export ${schema}\nexport ${stringifiedAlias}\n\nexport function use${parentService.name}${proc.name}Subscription`;
87
+ buff += `(args: z.infer<typeof ${inputIdentifier}>,extraOptions?: {
88
+ onError?: (errorMessage: string) => void; // Callback that executes when there's an error
89
+ onClose?: () => void; // Callback that executes when the connection has been closed by the server
90
+ })`;
91
+ buff += "{\n";
92
+ buff += `/*${proc.description}*/\n`;
93
+ // Initial setup of state.
94
+ buff += `const sourceRef = useRef<EventSource>();\n`;
95
+ buff += `const [messages, setMessages] = useState<Array<${outputTypeIdentifier}>>([]);\n`;
96
+ buff += `const [isConnected, setIsConnected] = useState<boolean>(false);\n`;
97
+ // Use effect main logic.
98
+ buff += `useEffect(() => {
99
+ if (
100
+ sourceRef.current &&
101
+ sourceRef.current?.readyState === sourceRef.current?.OPEN
102
+ ) {
103
+ // The connection is already stablished.
104
+ } else {
105
+ const targetURL = new URL("/_api", window.location.origin);
106
+ const fullPayload = {
107
+ service: "${parentService.name}",
108
+ procedure: "${proc.name}",
109
+ data: args,
110
+ };
111
+ const stringifiedArguments = JSON.stringify(fullPayload);
112
+ const encodedArguments = encodeURIComponent(stringifiedArguments);
113
+ targetURL.searchParams.set("payload", encodedArguments);
114
+
115
+ const source = new EventSource(targetURL);
116
+ sourceRef.current = source;
117
+
118
+ }
119
+
120
+ const aborter = new AbortController();
121
+
122
+
123
+ sourceRef.current.addEventListener(
124
+ "open",
125
+ () => {
126
+ setIsConnected(true);
127
+ },
128
+ {
129
+ signal: aborter.signal,
130
+ },
131
+ );
132
+
133
+ sourceRef.current.addEventListener(
134
+ "error",
135
+ () => {
136
+ if (extraOptions?.onError) {
137
+ extraOptions.onError("Failed to connect.");
138
+ }
139
+ setIsConnected(false);
140
+ console.warn("No errror handler has been set for the event source");
141
+ },
142
+ {
143
+ signal: aborter.signal,
144
+ },
145
+ );
146
+
147
+ sourceRef.current.addEventListener(
148
+ "content",
149
+ (ev) => {
150
+ try {
151
+ const data = JSON.parse(ev.data)
152
+ setMessages((prev) => [...prev, data]);
153
+ } catch {
154
+ if (extraOptions?.onError) {
155
+ extraOptions.onError("Failed to decode data")
156
+ }
157
+ }
158
+ },
159
+ {
160
+ signal: aborter.signal,
161
+ },
162
+ );
163
+
164
+ sourceRef.current.addEventListener(
165
+ "close",
166
+ () => {
167
+ sourceRef.current?.close();
168
+ if (extraOptions?.onClose) {
169
+ extraOptions.onClose();
170
+ }
171
+ },
172
+ {
173
+ signal: aborter.signal,
174
+ },
175
+ );
176
+
177
+ return () => {
178
+ aborter.abort();
179
+ };
180
+ }, [extraOptions, args]);
181
+
182
+
183
+ return {
184
+ messages,
185
+ isConnected,
186
+ };
187
+ }
188
+ `;
189
+ return await prettier.format(buff, { parser: "babel-ts" });
190
+ }
191
+ async function queryProcedureCodeGen(proc, parentService) {
192
+ // Extract the output typeAlias
193
+ const { outputTypeIdentifier, stringifiedAlias } = getOutputAlias(proc, parentService);
194
+ const inputIdentifier = `${parentService.name}${proc.name}QueryInputSchema`;
195
+ const schema = ztj(proc.input, {
196
+ errorMessages: true,
197
+ markdownDescription: true,
198
+ });
199
+ // @ts-ignore
200
+ const jsonSchema = jtz(schema, {
201
+ withJsdocs: true,
202
+ name: inputIdentifier,
203
+ });
204
+ let buff = `export ${jsonSchema}\nexport ${stringifiedAlias}\n\nexport function use${parentService.name}${proc.name}Query`;
205
+ const extraOptionsType = `Omit<UseQueryOptions<${outputTypeIdentifier}, Error, ${outputTypeIdentifier}, Array<string | z.infer<typeof ${inputIdentifier}>>>, "queryKey" | "queryFn">`;
206
+ buff += `(args: z.infer<typeof ${inputIdentifier}>, extraOptions?: ${extraOptionsType})`;
207
+ // Actual logic of the buffer here
208
+ buff += "{\n";
209
+ buff += `/*${proc.description}*/\n`;
210
+ // Form the keys array with args included
211
+ const staticKeys = [parentService.name, proc.name];
212
+ buff += `\treturn useQuery({queryKey: [${staticKeys.map((k) => `"${k}"`).join(", ")}, args],
213
+ queryFn: async () => {
214
+ const validationResult = await ${inputIdentifier}.safeParseAsync(args)
215
+ if (validationResult.error) {
216
+ console.error("Error on input validation of ${proc.name}", validationResult.error)
217
+ throw new Error(validationResult.error.message)
218
+ }
219
+
220
+
221
+
222
+ const response = await fetch('/_api', {
223
+ method: "POST",
224
+ body: JSON.stringify({
225
+ service: '${parentService.name}',
226
+ procedure: '${proc.name}',
227
+ data: validationResult.data
228
+ }),
229
+ })
230
+
231
+ if (!response.ok) {
232
+ let backendErrorMessage = ""
233
+ try {
234
+ backendErrorMessage = await response.text()
235
+ } catch {
236
+ backendErrorMessage = "No Error message returned from backen"
237
+ }
238
+ throw new Error("Query: ${proc.name} Non ok response: " + backendErrorMessage)
239
+ }
240
+
241
+ const rawResponse = await response.json()
242
+ return rawResponse["data"] as ${outputTypeIdentifier}
243
+ },
244
+ ...extraOptions
245
+ }
246
+ )`;
247
+ buff += "}";
248
+ return await prettier.format(buff, { parser: "babel-ts" });
249
+ }
250
+ async function GenerateServiceCode(service) {
251
+ const serviceBuffers = [];
252
+ for (const [pName, proc] of Object.entries(service.procedures)) {
253
+ let procedureCode = "";
254
+ if (proc.method === "MUTATION") {
255
+ procedureCode = await mutationProcedureCodeGen(proc, service);
256
+ }
257
+ else if (proc.method === "QUERY") {
258
+ procedureCode = await queryProcedureCodeGen(proc, service);
259
+ }
260
+ else if (proc.method === "SUBSCRIPTION") {
261
+ procedureCode = await subscriptionProcedureCodeGen(proc, service);
262
+ }
263
+ else {
264
+ console.error("UNKOWN METHOD!");
265
+ throw new Error("unk method");
266
+ }
267
+ serviceBuffers.push(procedureCode);
268
+ }
269
+ return serviceBuffers;
270
+ }
271
+ function serviceHasMethod(service, method) {
272
+ for (const [, proc] of Object.entries(service.procedures)) {
273
+ if (proc.method === method) {
274
+ return true;
275
+ }
276
+ }
277
+ return false;
278
+ }
279
+ async function getServiceCode(service, code) {
280
+ const prettified = await prettier.format(code, { parser: "babel-ts" });
281
+ return {
282
+ filename: service.name.toLowerCase() + ".service.ts",
283
+ code: code,
284
+ };
285
+ }
286
+ export async function GenerateCode(schema) {
287
+ const out = [];
288
+ for (const [key, service] of Object.entries(schema.services)) {
289
+ let finalBuffer = ``;
290
+ if (serviceHasMethod(service, "MUTATION")) {
291
+ finalBuffer += `import {useMutation, UseMutationOptions} from "@tanstack/react-query";\n`;
292
+ }
293
+ if (serviceHasMethod(service, "QUERY")) {
294
+ finalBuffer += `import {useQuery, UseQueryOptions} from "@tanstack/react-query";\n`;
295
+ }
296
+ if (serviceHasMethod(service, "SUBSCRIPTION")) {
297
+ finalBuffer += `import { useEffect, useRef, useState } from "react";\n`;
298
+ }
299
+ finalBuffer += 'import {z} from "zod"\n\n';
300
+ const buffers = await GenerateServiceCode(service);
301
+ finalBuffer += `// ---- Service Name: ${service.name} ----\n`;
302
+ finalBuffer += buffers.join("\n");
303
+ finalBuffer += "//----";
304
+ out.push(await getServiceCode(service, finalBuffer));
305
+ }
306
+ return out;
307
+ }
308
+ //# sourceMappingURL=client_side.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client_side.js","sourceRoot":"","sources":["../../src/schema/client_side.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { z } from "zod";
2
+ export type ProcedureType = `MUTATION` | `QUERY` | `SUBSCRIPTION`;
3
+ /**
4
+ * Represents a single procedure.
5
+ */
6
+ export interface Procedure<TMethod extends ProcedureType = ProcedureType, TInput extends z.Schema = z.AnyZodObject, TOuput extends z.Schema = z.AnyZodObject> {
7
+ // The name of the procdedure, must be unique and URI safe.
8
+ name: string;
9
+ // A description of what the procedure is supposed to do
10
+ description: string;
11
+ // The method to be used for the procedure
12
+ method: TMethod;
13
+ // If the method requires an input.
14
+ input: TInput;
15
+ // The output of the endpoint
16
+ output: TOuput;
17
+ }
18
+ /**
19
+ * Router, a container for multiple procedures. It can have a middleware which will run before each procedure.
20
+ */
21
+ type ServiceProcedures = {
22
+ [procName: string]: Procedure<ProcedureType, any, any>;
23
+ };
24
+ export declare class Service<TProcedures extends ServiceProcedures = {
25
+ [a: string]: Procedure<ProcedureType>;
26
+ }> {
27
+ middlewareDescription?: string | undefined;
28
+ name: string;
29
+ procedures: TProcedures;
30
+ constructor(name: string);
31
+ setMiddlewareDescription(middlewareDescription: string): this;
32
+ // Method to add a procedure - MUTATES the current instance
33
+ addProcedure<M extends ProcedureType, N extends string,
34
+ // Ensure Desc matches the Procedure interface (string | undefined if optional)
35
+ Desc extends string, // Or string | undefined if description is optional
36
+ I extends z.Schema, O extends z.Schema>(procDefinition: {
37
+ method: M;
38
+ name: N;
39
+ description: Desc; // Match interface (required or optional)
40
+ input: I;
41
+ output: O;
42
+ }): Service<
43
+ // The return *type* reflects the added procedure
44
+ TProcedures & {
45
+ [K in N]: Procedure<M, I, O> & {
46
+ method: M;
47
+ name: N;
48
+ description: Desc;
49
+ };
50
+ }>;
51
+ getProcedure<PName extends keyof TProcedures>(name: PName): TProcedures[PName];
52
+ }
53
+ export declare class APISchema<TServices extends Record<string, Service<any>> = {
54
+ [serviceName: string]: Service<any>;
55
+ }> {
56
+ services: TServices;
57
+ constructor(services?: TServices);
58
+ }
59
+ export {};
60
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,OAAO,GAAG,cAAc,CAAC;AAElE;;GAEG;AACH,MAAM,WAAW,SAAS,CACzB,OAAO,SAAS,aAAa,GAAG,aAAa,EAC7C,MAAM,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,YAAY,EACxC,MAAM,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,YAAY;IAExC,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IAEb,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IAEpB,0CAA0C;IAC1C,MAAM,EAAE,OAAO,CAAC;IAEhB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IAEd,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AAEH,KAAK,iBAAiB,GAAG;IACxB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC,aAAa,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;CACvD,CAAC;AAOF,qBAAa,OAAO,CACnB,WAAW,SAAS,iBAAiB,GAAG;IACvC,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,aAAa,CAAC,CAAC;CACtC;IAED,qBAAqB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAM;IAClB,UAAU,EAAE,WAAW,CAAC;IACxB,YAAY,IAAI,EAAE,MAAM,EAIvB;IAED,wBAAwB,CAAC,qBAAqB,EAAE,MAAM,QAGrD;IAED,2DAA2D;IAC3D,YAAY,CACX,CAAC,SAAS,aAAa,EACvB,CAAC,SAAS,MAAM;IAChB,+EAA+E;IAC/E,IAAI,SAAS,MAAM,EAAE,mDAAmD;IACxE,CAAC,SAAS,CAAC,CAAC,MAAM,EAClB,CAAC,SAAS,CAAC,CAAC,MAAM,EACjB,cAAc,EAAE;QACjB,MAAM,EAAE,CAAC,CAAC;QACV,IAAI,EAAE,CAAC,CAAC;QACR,WAAW,EAAE,IAAI,CAAC,CAAC,yCAAyC;QAC5D,KAAK,EAAE,CAAC,CAAC;QACT,MAAM,EAAE,CAAC,CAAC;KACV,GAAG,OAAO;IACV,iDAAiD;IACjD,WAAW,GAAG;SAEZ,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG;YAAE,MAAM,EAAE,CAAC,CAAC;YAAC,IAAI,EAAE,CAAC,CAAC;YAAC,WAAW,EAAE,IAAI,CAAA;SAAE;KACxE,CACD,CA6BA;IAED,YAAY,CAAC,KAAK,SAAS,MAAM,WAAW,EAC3C,IAAI,EAAE,KAAK,GACT,WAAW,CAAC,KAAK,CAAC,CAIpB;CACD;AAED,qBAAa,SAAS,CACrB,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG;IAChD,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CACpC;IAEM,QAAQ,EAAE,SAAS,CAAC;IAE3B,YAAY,QAAQ,GAAE,SAA2B,EAEhD;CACD"}
@@ -0,0 +1,41 @@
1
+ export class Service {
2
+ middlewareDescription;
3
+ name = "";
4
+ procedures;
5
+ constructor(name) {
6
+ this.name = name;
7
+ this.procedures = {};
8
+ }
9
+ setMiddlewareDescription(middlewareDescription) {
10
+ this.middlewareDescription = middlewareDescription;
11
+ return this;
12
+ }
13
+ // Method to add a procedure - MUTATES the current instance
14
+ addProcedure(procDefinition) {
15
+ // Create the procedure object explicitly matching the target type structure
16
+ const newProcedure = {
17
+ // Spread the definition to copy properties, ensuring all are included
18
+ ...procDefinition,
19
+ };
20
+ // Mutate the internal procedures map.
21
+ // Use a type assertion on `this.procedures` because we're adding a property
22
+ // dynamically. Treat it as a general record for the assignment.
23
+ this.procedures[procDefinition.name] = newProcedure;
24
+ // Return the *same instance* ('this') but CAST its type using 'as'.
25
+ // This tells TypeScript to treat 'this' going forward *as if* it has the
26
+ // new, more specific type that includes the added procedure.
27
+ return this;
28
+ }
29
+ getProcedure(name) {
30
+ // Access using the potentially broader type ServiceProcedures
31
+ // Or just directly access: this.procedures[name as keyof TProcedures]
32
+ return this.procedures[name];
33
+ }
34
+ }
35
+ export class APISchema {
36
+ services;
37
+ constructor(services = {}) {
38
+ this.services = services;
39
+ }
40
+ }
41
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAyCA,MAAM,OAAO,OAAO;IAKnB,qBAAqB,CAAsB;IAC3C,IAAI,GAAW,EAAE,CAAC;IAClB,UAAU,CAAc;IACxB,YAAY,IAAY,EAAE;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAEjB,IAAI,CAAC,UAAU,GAAG,EAAiB,CAAC;IAAA,CACpC;IAED,wBAAwB,CAAC,qBAA6B,EAAE;QACvD,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;QACnD,OAAO,IAAI,CAAC;IAAA,CACZ;IAED,2DAA2D;IAC3D,YAAY,CAOV,cAMD,EAMC;QACD,4EAA4E;QAC5E,MAAM,YAAY,GAId;YACH,sEAAsE;YACtE,GAAG,cAAc;SACjB,CAAC;QAEF,sCAAsC;QACtC,4EAA4E;QAC5E,gEAAgE;QAC/D,IAAI,CAAC,UAAgC,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC;QAE3E,oEAAoE;QACpE,yEAAyE;QACzE,6DAA6D;QAE7D,OAAO,IAQN,CAAC;IAAA,CACF;IAED,YAAY,CACX,IAAW,EACU;QACrB,8DAA8D;QAC9D,sEAAsE;QACtE,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAAA,CAC7B;CACD;AAED,MAAM,OAAO,SAAS;IAKd,QAAQ,CAAY;IAE3B,YAAY,QAAQ,GAAc,EAAe,EAAE;QAClD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAAA,CACzB;CACD"}
@@ -0,0 +1,22 @@
1
+ import type { Procedure, ProcedureType } from "../schema";
2
+ import type { z } from "zod";
3
+ export declare class Connection {
4
+ stream: ReadableStream<string>;
5
+ streamController: Bun.ReadableStreamController<string>;
6
+ constructor();
7
+ getStream(): ReadableStream<string>;
8
+ }
9
+ export declare class ConnectionWritter<P extends Procedure<ProcedureType, any, any>> {
10
+ private connection;
11
+ private procedureDefinition;
12
+ private closeFn;
13
+ private enqueueFn;
14
+ private closed;
15
+ private keepaliveInterval;
16
+ private _onCloseInternalCallback;
17
+ constructor(conn: Connection, procDefinition: P);
18
+ close(): Promise<void>;
19
+ write(message: z.infer<P["output"]>): Promise<void>;
20
+ onClose(callback: () => void): void;
21
+ }
22
+ //# sourceMappingURL=connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/server/connection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,qBAAa,UAAU;IACtB,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAC/B,gBAAgB,EAAE,GAAG,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACvD,cAYC;IAED,SAAS,2BAKR;CACD;AAED,qBAAa,iBAAiB,CAAC,CAAC,SAAS,SAAS,CAAC,aAAa,EAAE,GAAG,EAAE,GAAG,CAAC;IAC1E,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,mBAAmB,CAAI;IAC/B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,MAAM,CAAU;IAExB,OAAO,CAAC,iBAAiB,CAAQ;IACjC,OAAO,CAAC,wBAAwB,CAA2B;IAC3D,YAAY,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC,EAc9C;IAEK,KAAK,kBAqBV;IAEK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,iBAkBxC;IAED,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,QAE3B;CACD"}
@@ -0,0 +1,83 @@
1
+ export class Connection {
2
+ stream;
3
+ streamController;
4
+ constructor() {
5
+ let controllerToBeSet;
6
+ this.stream = new ReadableStream({
7
+ start(controller) {
8
+ controllerToBeSet = controller;
9
+ controller.enqueue(": Connected\n\n");
10
+ },
11
+ });
12
+ if (!controllerToBeSet) {
13
+ throw new Error("No controller has been captured");
14
+ }
15
+ this.streamController = controllerToBeSet;
16
+ }
17
+ getStream() {
18
+ if (this.stream === undefined) {
19
+ throw new Error("No stream has been stablished");
20
+ }
21
+ return this.stream;
22
+ }
23
+ }
24
+ export class ConnectionWritter {
25
+ connection;
26
+ procedureDefinition;
27
+ closeFn;
28
+ enqueueFn;
29
+ closed;
30
+ keepaliveInterval;
31
+ _onCloseInternalCallback;
32
+ constructor(conn, procDefinition) {
33
+ this.connection = conn;
34
+ this.procedureDefinition = procDefinition;
35
+ this.closeFn = this.connection.streamController.close.bind(this.connection.streamController);
36
+ this.enqueueFn = this.connection.streamController.enqueue.bind(this.connection.streamController);
37
+ this.closed = false;
38
+ this.keepaliveInterval = setInterval(() => {
39
+ this.enqueueFn(`: keepalive\n\n`);
40
+ }, 30_000);
41
+ }
42
+ async close() {
43
+ if (this.closed) {
44
+ console.log("The connection has been already closed");
45
+ return;
46
+ }
47
+ try {
48
+ this.enqueueFn(`event: close\ndata: close\n\n`);
49
+ }
50
+ catch {
51
+ console.log("[ZYNAPSE SUBSCRIPTION] Failed to send close connection event, has the connection already closed?");
52
+ }
53
+ clearInterval(this.keepaliveInterval);
54
+ if (this._onCloseInternalCallback) {
55
+ this._onCloseInternalCallback();
56
+ }
57
+ this.closeFn();
58
+ this.closed = true;
59
+ }
60
+ async write(message) {
61
+ if (this.closed) {
62
+ throw new Error("Attepted to write on closed connection.");
63
+ }
64
+ /* Write a message to the connection */
65
+ if (this.connection.streamController === undefined) {
66
+ console.error(new Error("Connection not found."));
67
+ return;
68
+ }
69
+ try {
70
+ const payload = JSON.stringify(message);
71
+ const buff = `event: content\ndata: ${payload}\n\n`;
72
+ this.enqueueFn(buff);
73
+ }
74
+ catch (e) {
75
+ console.log("Error at write method.", e);
76
+ // this.connection.streamController.enqueue(`event: error\ndata: ${e}\n\n`);
77
+ }
78
+ }
79
+ onClose(callback) {
80
+ this._onCloseInternalCallback = callback;
81
+ }
82
+ }
83
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/server/connection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { BunRequest } from "bun";
2
+ import { APISchema, Service, type Procedure, type ProcedureType } from "../schema";
3
+ import { z } from "zod";
4
+ import { ConnectionWritter } from "./connection";
5
+ type ContextType = Map<string, any>;
6
+ type SubscriptionHandler<P extends Procedure<ProcedureType, any, any>> = (args: z.infer<P["input"]>, request: BunRequest, context: ContextType, // Information that the middleware is capable of passing to the handler
7
+ connection: ConnectionWritter<P>) => Promise<undefined>;
8
+ type NormalProcedureHandler<P extends Procedure<ProcedureType, any, any>> = (args: z.infer<P["input"]>, request: BunRequest, context: ContextType) => Promise<z.infer<P["output"]>>;
9
+ type ProcedureHandler<P extends Procedure<ProcedureType, any, any>> = P["method"] extends `SUBSCRIPTION` ? SubscriptionHandler<P> : NormalProcedureHandler<P>;
10
+ type FullImplementation<SchemaT extends APISchema> = {
11
+ [ServiceName in keyof SchemaT["services"]]: ServiceImplementationHandlers<SchemaT["services"][ServiceName]>;
12
+ };
13
+ export type MiddlewareFunction = (req: BunRequest, procedureName: string, // The procedure name being executed.
14
+ context: ContextType) => Promise<void>;
15
+ type ServiceImplementationHandlers<ServiceT extends Service> = {
16
+ [ProcName in keyof ServiceT["procedures"]]: ProcedureHandler<ServiceT["procedures"][ProcName]>;
17
+ };
18
+ export declare class ServiceImplementationBuilder<ServiceT extends Service> {
19
+ middleware: MiddlewareFunction | undefined;
20
+ handlers: Partial<ServiceImplementationHandlers<ServiceT>>;
21
+ serviceSchema: ServiceT;
22
+ constructor(serviceSchema: ServiceT);
23
+ registerProcedureImplementation<ProcName extends keyof ServiceT["procedures"]>(procedureName: ProcName, handler: ProcedureHandler<ServiceT["procedures"][ProcName]>): this;
24
+ setMiddleware(middleware: MiddlewareFunction): this;
25
+ build(): ServiceImplementationHandlers<ServiceT>;
26
+ }
27
+ export declare class Server<SchemaT extends APISchema> {
28
+ schema: SchemaT;
29
+ implementation: FullImplementation<SchemaT>;
30
+ private _server;
31
+ private connectionPool;
32
+ constructor(schema: SchemaT, implementation: FullImplementation<SchemaT>);
33
+ private buildHandler;
34
+ start(port?: number): void;
35
+ stop(): Promise<void>;
36
+ }
37
+ export {};
38
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,234 @@
1
+ import "../schema";
2
+ import { z } from "zod";
3
+ import { Connection, ConnectionWritter } from "./connection";
4
+ async function* x() { }
5
+ export class ServiceImplementationBuilder {
6
+ middleware = undefined;
7
+ handlers = {};
8
+ serviceSchema;
9
+ constructor(serviceSchema) {
10
+ this.serviceSchema = serviceSchema;
11
+ }
12
+ registerProcedureImplementation(procedureName, handler) {
13
+ this.handlers[procedureName] = handler;
14
+ return this;
15
+ }
16
+ setMiddleware(middleware) {
17
+ this.middleware = middleware;
18
+ return this;
19
+ }
20
+ build() {
21
+ const requiredProcedureNames = Object.keys(this.serviceSchema.procedures);
22
+ const implementedProcedureNames = Object.keys(this.handlers);
23
+ const missingProcedures = requiredProcedureNames.filter((pName) => !implementedProcedureNames.includes(pName));
24
+ if (missingProcedures.length > 0) {
25
+ throw new Error(`Service implementation for "${this.serviceSchema.name}" is incomplete. Missing procedures: ${missingProcedures.join(", ")}`);
26
+ }
27
+ const extraProcedures = implementedProcedureNames.filter((pName) => !requiredProcedureNames.includes(pName));
28
+ if (extraProcedures.length > 0) {
29
+ // This case is less likely if using registerProcedureImplementation correctly
30
+ // due to the keyof constraint, but good for robustness.
31
+ console.warn(`Service implementation for "${this.serviceSchema.name}" has extra procedure handlers defined that are not in the schema: ${extraProcedures.join(", ")}`);
32
+ }
33
+ if (this.serviceSchema.middlewareDescription !== undefined &&
34
+ this.middleware === undefined) {
35
+ throw new Error(`A middleware for the service ${this.serviceSchema.name} is required but has not been implemented.`);
36
+ }
37
+ const finalHandlers = { ...this.handlers };
38
+ // Add middleware if defined
39
+ const result = {
40
+ ...(this.middleware && { middleware: this.middleware }),
41
+ // Spread the required handlers (already checked for existence)
42
+ ...finalHandlers,
43
+ }; // Assert final type
44
+ // Final check to ensure all required keys are present after assembly
45
+ for (const pName of requiredProcedureNames) {
46
+ if (!result[pName]) {
47
+ // This should ideally not happen if the logic above is correct, but acts as a safeguard.
48
+ throw new Error(`Internal error during build: Procedure "${pName}" handler missing in final object for service "${this.serviceSchema.name}".`);
49
+ }
50
+ }
51
+ return result;
52
+ }
53
+ }
54
+ const RequestBodySchema = z.object({
55
+ procedure: z.string({ message: "Procedure is not present in the body" }),
56
+ service: z.string({ message: "Service is not present in the body" }),
57
+ data: z.custom((d) => d !== undefined && d !== null, {
58
+ message: "Data must be present",
59
+ }),
60
+ });
61
+ async function* generatorTransform(inp) {
62
+ try {
63
+ for await (const chunk of inp) {
64
+ yield `event: content\ndata: ${JSON.stringify(chunk)}\n\n`;
65
+ }
66
+ }
67
+ catch (e) {
68
+ console.log("Error at iterator.", e);
69
+ yield `event: error\ndata: ${e}\n\n`;
70
+ }
71
+ }
72
+ export class Server {
73
+ schema;
74
+ implementation;
75
+ _server;
76
+ connectionPool;
77
+ constructor(schema, implementation) {
78
+ this.schema = schema;
79
+ this.implementation = implementation;
80
+ this.connectionPool = [];
81
+ }
82
+ buildHandler() {
83
+ return async (request) => {
84
+ // Only open under _api, if not, then close the connection
85
+ const urlObject = new URL(request.url);
86
+ if (urlObject.pathname.split("/")[1] !== "_api") {
87
+ console.log("[ZYNAPSE] The base url of the requested resource is invalid.");
88
+ return new Response(null, {
89
+ status: 400,
90
+ });
91
+ }
92
+ // Parse the request body
93
+ try {
94
+ let body;
95
+ if (urlObject.searchParams.has("payload")) {
96
+ const p = urlObject.searchParams.get("payload");
97
+ const decodedBody = decodeURIComponent(p);
98
+ body = JSON.parse(decodedBody);
99
+ }
100
+ else {
101
+ body = await request.json();
102
+ }
103
+ const parsedBody = await RequestBodySchema.safeParseAsync(body);
104
+ if (parsedBody.success === false) {
105
+ return new Response(parsedBody.error.message, {
106
+ status: 400,
107
+ });
108
+ }
109
+ // Now, lets check if we have that procedure.
110
+ const serviceDefinition = this.schema.services[parsedBody.data.service];
111
+ const implementationHandler = this.implementation[parsedBody.data.service];
112
+ if (implementationHandler === undefined ||
113
+ serviceDefinition === undefined) {
114
+ console.error(`[ZYNAPSE] The service ${parsedBody.data.service} doesn't exist`);
115
+ return new Response(`The service ${parsedBody.data.service} doesn't exist`, {
116
+ status: 404,
117
+ });
118
+ }
119
+ // Before proceding to the final execution, lets check if we have the procedure that the client is asking.
120
+ const procedureHandler = implementationHandler[parsedBody.data.procedure];
121
+ const procedureDefinition = serviceDefinition.getProcedure(parsedBody.data.procedure);
122
+ if (procedureHandler === undefined ||
123
+ procedureDefinition === undefined) {
124
+ console.log(`[ZYNAPSE] The procedure ${parsedBody.data.procedure} doesn't exist`);
125
+ return new Response(`The procedure ${parsedBody.data.procedure} doesn't exist`, {
126
+ status: 404,
127
+ });
128
+ }
129
+ // Validate the procedure input
130
+ const parsedArgumentsResult = await procedureDefinition.input.safeParseAsync(parsedBody.data.data);
131
+ if (parsedArgumentsResult.success === false) {
132
+ console.log(`[ZYNAPSE] The input has failed the validation: ${parsedArgumentsResult.error.message}`);
133
+ return new Response(`The input has failed the validation: ${parsedArgumentsResult.error.message}`, {
134
+ status: 400,
135
+ });
136
+ }
137
+ const ctx = new Map();
138
+ // Now, run the middleware if it exists
139
+ if (implementationHandler.middleware !== undefined) {
140
+ console.log("[ZYNAPSE] Running middleware");
141
+ try {
142
+ await implementationHandler.middleware(request, procedureDefinition.name, ctx);
143
+ }
144
+ catch (e) {
145
+ console.log("[ZYNAPSE] Error on middleware", e);
146
+ return new Response(undefined, {
147
+ status: 500,
148
+ });
149
+ }
150
+ }
151
+ try {
152
+ if (procedureDefinition.method === "SUBSCRIPTION") {
153
+ const conn = new Connection();
154
+ const connWritter = new ConnectionWritter(conn, procedureDefinition);
155
+ request.signal.addEventListener("abort", async () => {
156
+ await connWritter.close();
157
+ });
158
+ this.connectionPool.push(connWritter);
159
+ procedureHandler(parsedArgumentsResult.data, request, ctx, connWritter).catch((e) => {
160
+ console.error(`[ZYNAPSE] [${procedureDefinition.name}-${procedureDefinition.method}] ${e}`);
161
+ });
162
+ return new Response(conn.getStream(), {
163
+ headers: {
164
+ "Content-Type": "text/event-stream",
165
+ "Access-Control-Allow-Origin": "*", // NOTE: Temporal patch to be able to test in localhost
166
+ },
167
+ });
168
+ }
169
+ const output = await procedureHandler(parsedArgumentsResult.data, request, ctx);
170
+ return new Response(JSON.stringify({
171
+ data: output,
172
+ }), {
173
+ status: 200,
174
+ });
175
+ }
176
+ catch (e) {
177
+ console.error("[ZYNAPSE] The handler threw an error", e);
178
+ return new Response(`The endpoint returned an error ${e}`, {
179
+ status: 500,
180
+ });
181
+ }
182
+ }
183
+ catch (e) {
184
+ console.log("[ZYNAPSE] The body could not be parsed into JSON", e);
185
+ return new Response("Request cannot be parsed at the moment", {
186
+ status: 500,
187
+ });
188
+ }
189
+ };
190
+ }
191
+ start(port) {
192
+ if (this._server !== undefined) {
193
+ throw new Error("Cannot start 2 instances of the same server");
194
+ }
195
+ const _port = port || 3000;
196
+ const handler = this.buildHandler();
197
+ this._server = Bun.serve({
198
+ port: _port,
199
+ idleTimeout: 45,
200
+ routes: {
201
+ "/_api": handler,
202
+ },
203
+ async fetch(req) {
204
+ console.log(`[ZYNAPSE] Invalid request received. ${req.url}`);
205
+ return new Response(null, {
206
+ status: 404,
207
+ });
208
+ },
209
+ });
210
+ const stopServer = async () => {
211
+ await this.stop();
212
+ };
213
+ process.on("SIGTERM", stopServer);
214
+ process.on("SIGINT", stopServer);
215
+ process.on("SIGKILL", stopServer);
216
+ process.on("SIGHUP", stopServer);
217
+ console.log(`[ZYNAPSE] Listening on ${_port}`);
218
+ }
219
+ async stop() {
220
+ if (this._server === undefined) {
221
+ console.log("[ZYNAPSE] Nothing to stop");
222
+ return;
223
+ }
224
+ console.log(`[ZYNAPSE] Closing ${this.connectionPool.length} connections`);
225
+ for (const conn of this.connectionPool) {
226
+ await conn.close();
227
+ }
228
+ console.log("[ZYNAPSE] All connections has been closed.");
229
+ await this._server.stop();
230
+ console.log("[ZYNAPSE] Server stopped");
231
+ process.exit(0);
232
+ }
233
+ }
234
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAKO,WAAW,CAAC;AACnB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAsB7D,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,EAAC,CAAC;AAoBtB,MAAM,OAAO,4BAA4B;IACxC,UAAU,GAAmC,SAAS,CAAC;IACvD,QAAQ,GAAqD,EAAE,CAAC;IAChE,aAAa,CAAW;IACxB,YAAY,aAAuB,EAAE;QACpC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IAAA,CACnC;IAED,+BAA+B,CAG9B,aAAuB,EACvB,OAA2D,EAC1D;QACD,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC;QACvC,OAAO,IAAI,CAAC;IAAA,CACZ;IAED,aAAa,CAAC,UAA8B,EAAE;QAC7C,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,OAAO,IAAI,CAAC;IAAA,CACZ;IAED,KAAK,GAA4C;QAChD,MAAM,sBAAsB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAC1E,MAAM,yBAAyB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAE7D,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,MAAM,CACtD,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,yBAAyB,CAAC,QAAQ,CAAC,KAAK,CAAC,CACrD,CAAC;QAEF,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CACd,+BAA+B,IAAI,CAAC,aAAa,CAAC,IAAI,wCAAwC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC5H,CAAC;QACH,CAAC;QAED,MAAM,eAAe,GAAG,yBAAyB,CAAC,MAAM,CACvD,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,sBAAsB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAClD,CAAC;QAEF,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,8EAA8E;YAC9E,wDAAwD;YACxD,OAAO,CAAC,IAAI,CACX,+BAA+B,IAAI,CAAC,aAAa,CAAC,IAAI,sEAAsE,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACxJ,CAAC;QACH,CAAC;QAED,IACC,IAAI,CAAC,aAAa,CAAC,qBAAqB,KAAK,SAAS;YACtD,IAAI,CAAC,UAAU,KAAK,SAAS,EAC5B,CAAC;YACF,MAAM,IAAI,KAAK,CACd,gCAAgC,IAAI,CAAC,aAAa,CAAC,IAAI,4CAA4C,CACnG,CAAC;QACH,CAAC;QACD,MAAM,aAAa,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAE3C,4BAA4B;QAC5B,MAAM,MAAM,GAA4C;YACvD,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;YACvD,+DAA+D;YAC/D,GAAG,aAAa;SAC2B,CAAC,CAAC,oBAAoB;QAElE,qEAAqE;QACrE,KAAK,MAAM,KAAK,IAAI,sBAAsB,EAAE,CAAC;YAC5C,IAAI,CAAC,MAAM,CAAC,KAA4B,CAAC,EAAE,CAAC;gBAC3C,yFAAyF;gBACzF,MAAM,IAAI,KAAK,CACd,2CAA2C,KAAK,kDAAkD,IAAI,CAAC,aAAa,CAAC,IAAI,IAAI,CAC7H,CAAC;YACH,CAAC;QACF,CAAC;QAED,OAAO,MAAM,CAAC;IAAA,CACd;CACD;AAED,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,sCAAsC,EAAE,CAAC;IACxE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,oCAAoC,EAAE,CAAC;IACpE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAgB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,EAAE;QACnE,OAAO,EAAE,sBAAsB;KAC/B,CAAC;CACF,CAAC,CAAC;AAIH,KAAK,SAAS,CAAC,CAAC,kBAAkB,CACjC,GAAwB,EACC;IACzB,IAAI,CAAC;QACJ,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC;YAC/B,MAAM,yBAAyB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;QAC5D,CAAC;IACF,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC;QACrC,MAAM,uBAAuB,CAAC,MAAM,CAAC;IACtC,CAAC;AAAA,CACD;AAED,MAAM,OAAO,MAAM;IAClB,MAAM,CAAU;IAChB,cAAc,CAA8B;IACpC,OAAO,CAA6B;IACpC,cAAc,CAEpB;IACF,YAAY,MAAe,EAAE,cAA2C,EAAE;QACzE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;IAAA,CACzB;IAEO,YAAY,GAAG;QACtB,OAAO,KAAK,EAAE,OAAmB,EAAE,EAAE,CAAC;YACrC,0DAA0D;YAC1D,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACvC,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;gBACjD,OAAO,CAAC,GAAG,CACV,8DAA8D,CAC9D,CAAC;gBACF,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;oBACzB,MAAM,EAAE,GAAG;iBACX,CAAC,CAAC;YACJ,CAAC;YAED,yBAAyB;YACzB,IAAI,CAAC;gBACJ,IAAI,IAAS,CAAC;gBACd,IAAI,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC3C,MAAM,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC;oBACjD,MAAM,WAAW,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;oBAC1C,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;gBAChC,CAAC;qBAAM,CAAC;oBACP,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;gBAC7B,CAAC;gBACD,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;gBAChE,IAAI,UAAU,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;oBAClC,OAAO,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE;wBAC7C,MAAM,EAAE,GAAG;qBACX,CAAC,CAAC;gBACJ,CAAC;gBAED,6CAA6C;gBAC7C,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACxE,MAAM,qBAAqB,GAC1B,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC9C,IACC,qBAAqB,KAAK,SAAS;oBACnC,iBAAiB,KAAK,SAAS,EAC9B,CAAC;oBACF,OAAO,CAAC,KAAK,CACZ,yBAAyB,UAAU,CAAC,IAAI,CAAC,OAAO,gBAAgB,CAChE,CAAC;oBACF,OAAO,IAAI,QAAQ,CAClB,eAAe,UAAU,CAAC,IAAI,CAAC,OAAO,gBAAgB,EACtD;wBACC,MAAM,EAAE,GAAG;qBACX,CACD,CAAC;gBACH,CAAC;gBAED,0GAA0G;gBAC1G,MAAM,gBAAgB,GACrB,qBAAqB,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAClD,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,YAAY,CACzD,UAAU,CAAC,IAAI,CAAC,SAAS,CACuB,CAAC;gBAElD,IACC,gBAAgB,KAAK,SAAS;oBAC9B,mBAAmB,KAAK,SAAS,EAChC,CAAC;oBACF,OAAO,CAAC,GAAG,CACV,2BAA2B,UAAU,CAAC,IAAI,CAAC,SAAS,gBAAgB,CACpE,CAAC;oBACF,OAAO,IAAI,QAAQ,CAClB,iBAAiB,UAAU,CAAC,IAAI,CAAC,SAAS,gBAAgB,EAC1D;wBACC,MAAM,EAAE,GAAG;qBACX,CACD,CAAC;gBACH,CAAC;gBAED,+BAA+B;gBAC/B,MAAM,qBAAqB,GAC1B,MAAM,mBAAmB,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtE,IAAI,qBAAqB,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;oBAC7C,OAAO,CAAC,GAAG,CACV,kDAAkD,qBAAqB,CAAC,KAAK,CAAC,OAAO,EAAE,CACvF,CAAC;oBACF,OAAO,IAAI,QAAQ,CAClB,wCAAwC,qBAAqB,CAAC,KAAK,CAAC,OAAO,EAAE,EAC7E;wBACC,MAAM,EAAE,GAAG;qBACX,CACD,CAAC;gBACH,CAAC;gBAED,MAAM,GAAG,GAAgB,IAAI,GAAG,EAAE,CAAC;gBAEnC,uCAAuC;gBACvC,IAAI,qBAAqB,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;oBACpD,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;oBAC5C,IAAI,CAAC;wBACJ,MACC,qBAAqB,CAAC,UACtB,CAAC,OAAO,EAAE,mBAAmB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;oBAC3C,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACZ,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;wBAChD,OAAO,IAAI,QAAQ,CAAC,SAAS,EAAE;4BAC9B,MAAM,EAAE,GAAG;yBACX,CAAC,CAAC;oBACJ,CAAC;gBACF,CAAC;gBAED,IAAI,CAAC;oBACJ,IAAI,mBAAmB,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;wBACnD,MAAM,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC;wBAC9B,MAAM,WAAW,GAAG,IAAI,iBAAiB,CACxC,IAAI,EACJ,mBAAmB,CACnB,CAAC;wBACF,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC;4BACpD,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC;wBAAA,CAC1B,CAAC,CAAC;wBACH,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wBAEtC,gBAAgB,CACf,qBAAqB,CAAC,IAAI,EAC1B,OAAO,EACP,GAAG,EACH,WAAW,CACX,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;4BACd,OAAO,CAAC,KAAK,CACZ,cAAc,mBAAmB,CAAC,IAAI,IAAI,mBAAmB,CAAC,MAAM,KAAK,CAAC,EAAE,CAC5E,CAAC;wBAAA,CACF,CAAC,CAAC;wBAEH,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE;4BACrC,OAAO,EAAE;gCACR,cAAc,EAAE,mBAAmB;gCACnC,6BAA6B,EAAE,GAAG,EAAE,uDAAuD;6BAC3F;yBACD,CAAC,CAAC;oBACJ,CAAC;oBACD,MAAM,MAAM,GAAG,MACd,gBAGA,CAAC,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;oBAE5C,OAAO,IAAI,QAAQ,CAClB,IAAI,CAAC,SAAS,CAAC;wBACd,IAAI,EAAE,MAAM;qBACZ,CAAC,EACF;wBACC,MAAM,EAAE,GAAG;qBACX,CACD,CAAC;gBACH,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACZ,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,CAAC,CAAC,CAAC;oBACzD,OAAO,IAAI,QAAQ,CAAC,kCAAkC,CAAC,EAAE,EAAE;wBAC1D,MAAM,EAAE,GAAG;qBACX,CAAC,CAAC;gBACJ,CAAC;YACF,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,OAAO,CAAC,GAAG,CAAC,kDAAkD,EAAE,CAAC,CAAC,CAAC;gBACnE,OAAO,IAAI,QAAQ,CAAC,wCAAwC,EAAE;oBAC7D,MAAM,EAAE,GAAG;iBACX,CAAC,CAAC;YACJ,CAAC;QAAA,CACD,CAAC;IAAA,CACF;IAED,KAAK,CAAC,IAAa,EAAE;QACpB,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAChE,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,IAAI,IAAI,CAAC;QAE3B,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAEpC,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC;YACxB,IAAI,EAAE,KAAK;YACX,WAAW,EAAE,EAAE;YACf,MAAM,EAAE;gBACP,OAAO,EAAE,OAAO;aAChB;YACD,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE;gBAChB,OAAO,CAAC,GAAG,CAAC,uCAAuC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;gBAC9D,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;oBACzB,MAAM,EAAE,GAAG;iBACX,CAAC,CAAC;YAAA,CACH;SACD,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,KAAK,IAAI,EAAE,CAAC;YAC9B,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAAA,CAClB,CAAC;QAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAClC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QACjC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAClC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAEjC,OAAO,CAAC,GAAG,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;IAAA,CAC/C;IAED,KAAK,CAAC,IAAI,GAAG;QACZ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YACzC,OAAO;QACR,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,CAAC,cAAc,CAAC,MAAM,cAAc,CAAC,CAAC;QAC3E,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;QAE1D,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAAA,CAChB;CACD"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "zynapse",
3
+ "version": "0.1.0",
4
+ "description": "A TypeScript library providing a schema-based API system with type-safe server implementations",
5
+ "type": "module",
6
+ "main": "./dist/schema/index.js",
7
+ "module": "./dist/schema/index.js",
8
+ "types": "./dist/schema/index.d.ts",
9
+ "exports": {
10
+ "./schema": {
11
+ "types": "./dist/schema/index.d.ts",
12
+ "import": "./dist/schema/index.js",
13
+ "default": "./dist/schema/index.js"
14
+ },
15
+ "./server": {
16
+ "types": "./dist/server/index.d.ts",
17
+ "import": "./dist/server/index.js",
18
+ "default": "./dist/server/index.js"
19
+ }
20
+ },
21
+ "bin": {
22
+ "zynapse-cli": "./dist/cli/index.js"
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "README.md",
27
+ "LICENSE"
28
+ ],
29
+ "scripts": {
30
+ "build": "tsgo -p tsconfig.build.json",
31
+ "prepublishOnly": "bun run build",
32
+ "test": "bun test"
33
+ },
34
+ "keywords": [
35
+ "typescript",
36
+ "api",
37
+ "schema",
38
+ "zod",
39
+ "type-safe"
40
+ ],
41
+ "devDependencies": {
42
+ "@types/bun": "^1.3.2",
43
+ "@typescript/native-preview": "^7.0.0-dev.20250606.1",
44
+ "typescript": "^5.7.2"
45
+ },
46
+ "peerDependencies": {
47
+ "typescript": "^5"
48
+ },
49
+ "dependencies": {
50
+ "json-schema-to-zod": "^2.6.1",
51
+ "prettier": "^3.5.3",
52
+ "zod": "^3.24.3",
53
+ "zod-to-json-schema": "^3.24.6",
54
+ "zod-to-ts": "^1.2.0"
55
+ }
56
+ }