@inflector/aura 0.2.9 → 0.2.11

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/dist/bin.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AA+KA,wBAAgB,KAAK,CAAC,MAAM,UAAQ,QA2CnC;AA0aD,wBAAsB,GAAG,kBAsExB"}
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AAmLA,wBAAgB,KAAK,CAAC,MAAM,UAAQ,QAgDnC;AAwaD,wBAAsB,GAAG,kBAsExB"}
package/dist/bin.js CHANGED
@@ -125,7 +125,12 @@ function scanFolderWithTypes(folder) {
125
125
  function objectToTypeWithReturn(name, obj, auraType = "AuraFunctionHandler") {
126
126
  const lines = [];
127
127
  function toFnType(returnType) {
128
- return `(...args: any[]) => Promise<${returnType}>`;
128
+ if (returnType === "SSEHandler") {
129
+ return `(...args: any[]) => Promise<SSEEvent>`;
130
+ }
131
+ else {
132
+ return `(...args: any[]) => Promise<${returnType}>`;
133
+ }
129
134
  }
130
135
  function recurse(o, indent = " ") {
131
136
  const inner = [];
@@ -163,6 +168,11 @@ export function build(silent = false) {
163
168
  // - SSEHandler is NOT generic
164
169
  // - Client exposes parsed data, not raw SSE events
165
170
  const header = `
171
+ export type SSEEvent = {
172
+ event: string;
173
+ data: any;
174
+ };
175
+
166
176
  export type SSEStream<T> = {
167
177
  onMessage(cb: (data: T) => void): Promise<void>;
168
178
  abort(): void;
@@ -1,12 +1,2 @@
1
- export type SSEEvent<T = unknown> = {
2
- event: string;
3
- data: T;
4
- raw: string;
5
- };
6
- export type SSEHandler<T> = (evt: SSEEvent<T>) => void;
7
- export type FunctionResult<TJson, TSse> = Promise<TJson> | {
8
- onMessage(cb: SSEHandler<TSse>): Promise<void>;
9
- abort(): void;
10
- };
11
- export declare function createFunctionHandler<TFunctions extends Record<string, any>>(workspace: string): TFunctions;
1
+ export declare function createFunctionHandler(workspace: string, functionsFolder?: string): any;
12
2
  //# sourceMappingURL=function.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"function.d.ts","sourceRoot":"","sources":["../src/function.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,CAAC,CAAC,GAAG,OAAO,IAAI;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,CAAC,CAAC;IACR,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAEvD,MAAM,MAAM,cAAc,CAAC,KAAK,EAAE,IAAI,IAClC,OAAO,CAAC,KAAK,CAAC,GACd;IACE,SAAS,CAAC,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAqDN,wBAAgB,qBAAqB,CAAC,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1E,SAAS,EAAE,MAAM,cAyDlB"}
1
+ {"version":3,"file":"function.d.ts","sourceRoot":"","sources":["../src/function.ts"],"names":[],"mappings":"AAAA,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,eAAe,CAAC,EAAE,MAAM,GACvB,GAAG,CAkJL"}
package/dist/function.js CHANGED
@@ -1,89 +1,130 @@
1
- async function parseSSE(response, onMessage, signal) {
2
- if (!response.body)
3
- throw new Error("Missing response body");
4
- const reader = response.body.getReader();
5
- const decoder = new TextDecoder();
6
- let buffer = "";
7
- while (true) {
8
- const { value, done } = await reader.read();
9
- if (done)
10
- break;
11
- buffer += decoder.decode(value, { stream: true });
12
- const chunks = buffer.split("\n\n");
13
- buffer = chunks.pop() ?? "";
14
- for (const chunk of chunks) {
15
- let event = "message";
16
- const dataLines = [];
17
- for (const line of chunk.split("\n")) {
18
- if (line.startsWith("event:")) {
19
- event = line.slice(6).trim();
20
- }
21
- if (line.startsWith("data:")) {
22
- dataLines.push(line.slice(5).trim());
23
- }
24
- }
25
- if (dataLines.length === 0)
26
- continue;
27
- const raw = dataLines.join("\n");
28
- let parsed = raw;
29
- try {
30
- parsed = JSON.parse(raw);
31
- }
32
- catch { }
33
- onMessage({
34
- event,
35
- data: parsed,
36
- raw,
37
- });
38
- }
39
- }
40
- }
41
- export function createFunctionHandler(workspace) {
42
- return new Proxy({}, {
43
- get(_, fnName) {
44
- return (...args) => {
45
- const controller = new AbortController();
46
- const url = ["api", "fn", workspace, fnName].join("/");
47
- const body = args.length === 1 && args[0] instanceof FormData
48
- ? args[0]
49
- : JSON.stringify(args[0] ?? {});
1
+ export function createFunctionHandler(workspace, functionsFolder) {
2
+ const handler = new Proxy({}, {
3
+ get(_, prop) {
4
+ return createNestedProxy([prop]);
5
+ },
6
+ });
7
+ function createNestedProxy(path) {
8
+ // Target function is just a placeholder
9
+ return new Proxy(() => { }, {
10
+ get(_, prop) {
11
+ return createNestedProxy([...path, prop]);
12
+ },
13
+ // 1. Remove 'async' here to prevent native Promise wrapping
14
+ apply(_, __, args) {
15
+ const url = ["api", "fn", workspace, ...path].join("/");
16
+ const isFormData = args != null && args.length === 1 && args[0] instanceof FormData;
17
+ const body = isFormData ? args[0] : JSON.stringify(args[0] ?? {});
50
18
  const headers = {
51
19
  Accept: "text/event-stream,application/json",
52
20
  };
53
- if (!(body instanceof FormData)) {
21
+ if (!isFormData)
54
22
  headers["Content-Type"] = "application/json";
55
- }
56
- const request = fetch(url, {
23
+ // 2. Start the fetch properly (without await)
24
+ const requestPromise = fetch(url, {
57
25
  method: "POST",
58
26
  body,
59
27
  headers,
60
28
  credentials: "include",
61
- signal: controller.signal,
62
29
  });
63
- return {
64
- async onMessage(cb) {
65
- const res = await request;
66
- const type = res.headers.get("Content-Type") ?? "";
67
- if (!type.includes("text/event-stream")) {
68
- throw new Error("Response is not SSE");
69
- }
70
- await parseSSE(res, cb, controller.signal);
30
+ // 3. Return a custom "Thenable" object with full Promise interface
31
+ const thenable = {
32
+ then(onFulfilled, onRejected) {
33
+ requestPromise
34
+ .then(async (response) => {
35
+ const contentType = response.headers.get("Content-Type") || "";
36
+ // ─────────────────────────────────────────────
37
+ // SSE PATH
38
+ // ─────────────────────────────────────────────
39
+ if (contentType.includes("text/event-stream")) {
40
+ if (!response.body) {
41
+ if (onRejected)
42
+ onRejected(new Error("Response body is null"));
43
+ return;
44
+ }
45
+ const reader = response.body.getReader();
46
+ const decoder = new TextDecoder("utf-8");
47
+ let buffer = "";
48
+ try {
49
+ while (true) {
50
+ const { value, done } = await reader.read();
51
+ if (done)
52
+ break;
53
+ buffer += decoder.decode(value, { stream: true });
54
+ // Split by SSE message delimiter
55
+ const parts = buffer.split("\n\n");
56
+ buffer = parts.pop() || ""; // Keep incomplete chunk
57
+ for (const part of parts) {
58
+ if (!part.trim())
59
+ continue;
60
+ const lines = part.split("\n");
61
+ let eventName = "message"; // Default SSE event type
62
+ const dataLines = [];
63
+ for (const line of lines) {
64
+ if (line.startsWith("event: ")) {
65
+ eventName = line.replace(/^event: /, "").trim();
66
+ }
67
+ else if (line.startsWith("data: ")) {
68
+ dataLines.push(line.replace(/^data: /, ""));
69
+ }
70
+ }
71
+ const message = dataLines.join("\n");
72
+ if (message) {
73
+ try {
74
+ // Emit parsed JSON along with the event name
75
+ const parsedData = JSON.parse(message);
76
+ onFulfilled({
77
+ event: eventName,
78
+ data: parsedData,
79
+ });
80
+ }
81
+ catch {
82
+ // Or emit raw string if parsing fails
83
+ onFulfilled({
84
+ event: eventName,
85
+ data: message,
86
+ });
87
+ }
88
+ }
89
+ }
90
+ }
91
+ }
92
+ catch (err) {
93
+ if (onRejected)
94
+ onRejected(err);
95
+ }
96
+ }
97
+ // ─────────────────────────────────────────────
98
+ // NORMAL JSON PATH
99
+ // ─────────────────────────────────────────────
100
+ else {
101
+ const data = await response.json();
102
+ onFulfilled(data.data ?? data);
103
+ }
104
+ })
105
+ .catch((err) => {
106
+ if (onRejected)
107
+ onRejected(err);
108
+ });
109
+ // Return 'this' to allow chaining
110
+ return thenable;
71
111
  },
72
- abort() {
73
- controller.abort();
112
+ catch(onRejected) {
113
+ return thenable.then(() => { }, onRejected);
74
114
  },
75
- async then(resolve, reject) {
76
- try {
77
- const res = await request;
78
- const json = await res.json();
79
- resolve(json.data ?? json);
80
- }
81
- catch (e) {
82
- reject?.(e);
83
- }
115
+ finally(onFinally) {
116
+ return thenable.then((value) => {
117
+ onFinally?.();
118
+ return value;
119
+ }, (err) => {
120
+ onFinally?.();
121
+ throw err;
122
+ });
84
123
  },
85
124
  };
86
- };
87
- },
88
- });
125
+ return thenable;
126
+ },
127
+ });
128
+ }
129
+ return handler;
89
130
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inflector/aura",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",