@parcae/sdk 0.3.3 → 0.4.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/dist/{chunk-IETH2XOR.js → chunk-KFISHMU4.js} +129 -175
- package/dist/chunk-KFISHMU4.js.map +1 -0
- package/dist/client-CeIUZzoo.d.ts +38 -0
- package/dist/index.d.ts +41 -23
- package/dist/index.js +1 -1
- package/dist/react/index.d.ts +2 -17
- package/dist/react/index.js +25 -17
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-IETH2XOR.js.map +0 -1
- package/dist/client-uWUdynht.d.ts +0 -63
|
@@ -5,136 +5,104 @@ import { EventEmitter } from 'eventemitter3';
|
|
|
5
5
|
import ShortId from 'short-unique-id';
|
|
6
6
|
import { Model, FrontendAdapter } from '@parcae/model';
|
|
7
7
|
|
|
8
|
-
// src/
|
|
8
|
+
// src/auth-gate.ts
|
|
9
|
+
var AuthGate = class {
|
|
10
|
+
_state = "pending";
|
|
11
|
+
_resolve = null;
|
|
12
|
+
_promise;
|
|
13
|
+
constructor() {
|
|
14
|
+
this._promise = this._makePending();
|
|
15
|
+
}
|
|
16
|
+
get state() {
|
|
17
|
+
return this._state;
|
|
18
|
+
}
|
|
19
|
+
get ready() {
|
|
20
|
+
return this._promise;
|
|
21
|
+
}
|
|
22
|
+
resolve() {
|
|
23
|
+
this._state = "ready";
|
|
24
|
+
if (this._resolve) {
|
|
25
|
+
this._resolve();
|
|
26
|
+
this._resolve = null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
reset() {
|
|
30
|
+
if (this._state === "ready") {
|
|
31
|
+
this._state = "pending";
|
|
32
|
+
this._promise = this._makePending();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
_makePending() {
|
|
36
|
+
return new Promise((r) => {
|
|
37
|
+
this._resolve = r;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
};
|
|
9
41
|
var uid = new ShortId({ length: 10 });
|
|
10
|
-
var SOCKET_CONNECTIONS = /* @__PURE__ */ new Map();
|
|
11
42
|
var SocketTransport = class extends EventEmitter {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
43
|
+
auth = new AuthGate();
|
|
44
|
+
isConnected = false;
|
|
45
|
+
isLoading = false;
|
|
46
|
+
userId = null;
|
|
47
|
+
socket;
|
|
16
48
|
url;
|
|
17
49
|
version;
|
|
18
|
-
socketPath;
|
|
19
|
-
waitForAuth = null;
|
|
20
|
-
resolveAuth = null;
|
|
21
50
|
inflight = /* @__PURE__ */ new Map();
|
|
22
|
-
loading;
|
|
23
|
-
isLoading = true;
|
|
24
|
-
isConnected = false;
|
|
25
|
-
isConnecting = false;
|
|
26
|
-
authVersion = 0;
|
|
27
51
|
constructor(config) {
|
|
28
52
|
super();
|
|
29
53
|
this.url = config.url;
|
|
30
|
-
this.apiKey = config.key ?? null;
|
|
31
54
|
this.version = config.version ?? "v1";
|
|
32
|
-
this.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
this.apiKey = key;
|
|
38
|
-
this.isLoading = true;
|
|
39
|
-
this.loading = this.init(key);
|
|
40
|
-
await this.loading;
|
|
41
|
-
}
|
|
42
|
-
// ── Init ──────────────────────────────────────────────────────────────
|
|
43
|
-
async init(key) {
|
|
44
|
-
this.isLoading = true;
|
|
45
|
-
this.isConnecting = true;
|
|
46
|
-
try {
|
|
47
|
-
this.key = typeof key === "function" ? await key() : key;
|
|
48
|
-
const socketKey = `${this.url}:${this.version}`;
|
|
49
|
-
if (!SOCKET_CONNECTIONS.has(socketKey)) {
|
|
50
|
-
SOCKET_CONNECTIONS.set(
|
|
51
|
-
socketKey,
|
|
52
|
-
SocketIO(this.url, {
|
|
53
|
-
path: this.socketPath,
|
|
54
|
-
agent: true,
|
|
55
|
-
transports: ["websocket"],
|
|
56
|
-
withCredentials: true,
|
|
57
|
-
query: { key: this.key ?? void 0, compression: true }
|
|
58
|
-
})
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
this.socket = SOCKET_CONNECTIONS.get(socketKey);
|
|
62
|
-
if (this.key) {
|
|
63
|
-
const prevResolve = this.resolveAuth;
|
|
64
|
-
this.waitForAuth = new Promise((resolve) => {
|
|
65
|
-
this.resolveAuth = resolve;
|
|
66
|
-
this.socket.emit("authenticate", this.key, () => {
|
|
67
|
-
this.waitForAuth = null;
|
|
68
|
-
this.resolveAuth = null;
|
|
69
|
-
this.authVersion++;
|
|
70
|
-
this.emit("authenticated");
|
|
71
|
-
if (prevResolve) prevResolve();
|
|
72
|
-
resolve();
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
} else {
|
|
76
|
-
this.waitForAuth = null;
|
|
77
|
-
this.resolveAuth = null;
|
|
78
|
-
}
|
|
79
|
-
this.isLoading = false;
|
|
80
|
-
} catch (error) {
|
|
81
|
-
this.isLoading = false;
|
|
82
|
-
this.isConnecting = false;
|
|
83
|
-
this.emit("error", error);
|
|
84
|
-
throw error;
|
|
85
|
-
}
|
|
86
|
-
this.setupEvents();
|
|
87
|
-
}
|
|
88
|
-
setupEvents() {
|
|
89
|
-
if (!this.socket) return;
|
|
90
|
-
for (const { event, handler } of this.pendingHandlers) {
|
|
91
|
-
this.socket.on(event, handler);
|
|
92
|
-
}
|
|
93
|
-
this.pendingHandlers = [];
|
|
94
|
-
let hasConnected = this.isConnected;
|
|
95
|
-
this.socket.off("connect");
|
|
96
|
-
this.socket.off("disconnect");
|
|
97
|
-
this.socket.off("error");
|
|
55
|
+
this.socket = SocketIO(this.url, {
|
|
56
|
+
path: config.path ?? "/ws",
|
|
57
|
+
transports: ["websocket"],
|
|
58
|
+
withCredentials: true
|
|
59
|
+
});
|
|
98
60
|
this.socket.on("connect", () => {
|
|
99
|
-
const
|
|
61
|
+
const wasConnected = this.isConnected;
|
|
100
62
|
this.isConnected = true;
|
|
101
|
-
this.
|
|
102
|
-
hasConnected = true;
|
|
103
|
-
if (wasDisconnected && this.key) {
|
|
104
|
-
this.socket.emit("authenticate", this.key, () => {
|
|
105
|
-
this.emit("reconnected");
|
|
106
|
-
});
|
|
107
|
-
} else {
|
|
108
|
-
this.emit(wasDisconnected ? "reconnected" : "connected");
|
|
109
|
-
}
|
|
63
|
+
this.emit(wasConnected ? "reconnected" : "connected");
|
|
110
64
|
});
|
|
111
65
|
this.socket.on("disconnect", () => {
|
|
112
66
|
this.isConnected = false;
|
|
67
|
+
this.auth.reset();
|
|
113
68
|
this.emit("disconnected");
|
|
114
69
|
});
|
|
115
|
-
this.socket.on("error", (
|
|
116
|
-
this.emit("error",
|
|
70
|
+
this.socket.on("error", (err) => {
|
|
71
|
+
this.emit("error", err);
|
|
117
72
|
});
|
|
118
73
|
}
|
|
119
|
-
// ──
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
this.
|
|
131
|
-
|
|
132
|
-
return req;
|
|
74
|
+
// ── Authenticate ──────────────────────────────────────────────────
|
|
75
|
+
/**
|
|
76
|
+
* Authenticate with the backend. Resolves the AuthGate when done.
|
|
77
|
+
*
|
|
78
|
+
* - token=string → send to server, wait for confirmation
|
|
79
|
+
* - token=null → no auth, resolve gate immediately (unauthenticated)
|
|
80
|
+
*/
|
|
81
|
+
async authenticate(token) {
|
|
82
|
+
this.auth.reset();
|
|
83
|
+
this.userId = null;
|
|
84
|
+
if (!token) {
|
|
85
|
+
this.auth.resolve();
|
|
86
|
+
return { userId: null };
|
|
133
87
|
}
|
|
134
|
-
|
|
88
|
+
if (!this.socket.connected) {
|
|
89
|
+
await new Promise((resolve) => {
|
|
90
|
+
if (this.socket.connected) return resolve();
|
|
91
|
+
this.socket.once("connect", () => resolve());
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return new Promise((resolve) => {
|
|
95
|
+
this.socket.emit("authenticate", token, (response) => {
|
|
96
|
+
this.userId = response?.userId ?? null;
|
|
97
|
+
this.auth.resolve();
|
|
98
|
+
resolve({ userId: this.userId });
|
|
99
|
+
});
|
|
100
|
+
});
|
|
135
101
|
}
|
|
136
|
-
|
|
137
|
-
|
|
102
|
+
// ── Request/Response ──────────────────────────────────────────────
|
|
103
|
+
async fetch(method, path, data = {}) {
|
|
104
|
+
await this.auth.ready;
|
|
105
|
+
if (!this.socket.connected) {
|
|
138
106
|
await new Promise((resolve, reject) => {
|
|
139
107
|
if (this.socket.connected) return resolve();
|
|
140
108
|
const timeout = setTimeout(() => {
|
|
@@ -147,7 +115,7 @@ var SocketTransport = class extends EventEmitter {
|
|
|
147
115
|
};
|
|
148
116
|
const onError = (err) => {
|
|
149
117
|
cleanup();
|
|
150
|
-
reject(
|
|
118
|
+
reject(err);
|
|
151
119
|
};
|
|
152
120
|
const cleanup = () => {
|
|
153
121
|
clearTimeout(timeout);
|
|
@@ -158,21 +126,39 @@ var SocketTransport = class extends EventEmitter {
|
|
|
158
126
|
this.socket.once("connect_error", onError);
|
|
159
127
|
});
|
|
160
128
|
}
|
|
129
|
+
const upper = method.toUpperCase();
|
|
130
|
+
if (upper === "GET") {
|
|
131
|
+
const dedupeKey = `${path}:${JSON.stringify(data)}`;
|
|
132
|
+
const existing = this.inflight.get(dedupeKey);
|
|
133
|
+
if (existing) return existing;
|
|
134
|
+
const req = this._call(method, path, data);
|
|
135
|
+
this.inflight.set(dedupeKey, req);
|
|
136
|
+
req.finally(() => this.inflight.delete(dedupeKey));
|
|
137
|
+
return req;
|
|
138
|
+
}
|
|
139
|
+
return this._call(method, path, data);
|
|
140
|
+
}
|
|
141
|
+
_call(method, path, data) {
|
|
161
142
|
const id = uid.rnd();
|
|
162
143
|
return new Promise((resolve, reject) => {
|
|
144
|
+
const timeout = setTimeout(() => {
|
|
145
|
+
this.socket.off(id);
|
|
146
|
+
reject(new Error(`RPC timeout: ${method} ${path}`));
|
|
147
|
+
}, 3e4);
|
|
163
148
|
this.socket.once(id, (msg) => {
|
|
149
|
+
clearTimeout(timeout);
|
|
164
150
|
try {
|
|
165
151
|
const uncompressed = pako.ungzip(msg, { to: "string" });
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
else
|
|
152
|
+
const parsed = decompress(JSON.parse(uncompressed));
|
|
153
|
+
if (parsed.success) {
|
|
154
|
+
resolve(parsed.result);
|
|
155
|
+
} else {
|
|
171
156
|
reject(
|
|
172
157
|
new Error(
|
|
173
|
-
message || error ||
|
|
158
|
+
parsed.message || parsed.error || `${method} ${path} failed`
|
|
174
159
|
)
|
|
175
160
|
);
|
|
161
|
+
}
|
|
176
162
|
} catch (err) {
|
|
177
163
|
reject(err);
|
|
178
164
|
}
|
|
@@ -187,58 +173,40 @@ var SocketTransport = class extends EventEmitter {
|
|
|
187
173
|
});
|
|
188
174
|
}
|
|
189
175
|
async get(path, data) {
|
|
190
|
-
return this.fetch("
|
|
176
|
+
return this.fetch("GET", path, data);
|
|
191
177
|
}
|
|
192
178
|
async post(path, data) {
|
|
193
|
-
return this.fetch("
|
|
179
|
+
return this.fetch("POST", path, data);
|
|
194
180
|
}
|
|
195
181
|
async put(path, data) {
|
|
196
|
-
return this.fetch("
|
|
182
|
+
return this.fetch("PUT", path, data);
|
|
197
183
|
}
|
|
198
184
|
async patch(path, data) {
|
|
199
|
-
return this.fetch("
|
|
185
|
+
return this.fetch("PATCH", path, data);
|
|
200
186
|
}
|
|
201
187
|
async delete(path, data) {
|
|
202
|
-
return this.fetch("
|
|
188
|
+
return this.fetch("DELETE", path, data);
|
|
203
189
|
}
|
|
204
|
-
// ── Subscriptions
|
|
190
|
+
// ── Subscriptions ─────────────────────────────────────────────────
|
|
205
191
|
subscribe(event, handler) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
} else {
|
|
209
|
-
this.pendingHandlers.push({ event, handler });
|
|
210
|
-
}
|
|
211
|
-
return () => this.unsubscribe(event, handler);
|
|
192
|
+
this.socket.on(event, handler);
|
|
193
|
+
return () => this.socket.off(event, handler);
|
|
212
194
|
}
|
|
213
195
|
unsubscribe(event, handler) {
|
|
214
|
-
|
|
215
|
-
this.pendingHandlers = this.pendingHandlers.filter(
|
|
216
|
-
(h) => !(h.event === event && (!handler || h.handler === handler))
|
|
217
|
-
);
|
|
196
|
+
this.socket.off(event, handler);
|
|
218
197
|
}
|
|
219
|
-
// ── Control
|
|
198
|
+
// ── Control ───────────────────────────────────────────────────────
|
|
220
199
|
async send(event, ...args) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
if (this.socket.connected) return resolve();
|
|
224
|
-
this.socket.once("connect", () => resolve());
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
if (this.waitForAuth) await this.waitForAuth;
|
|
228
|
-
if (this.socket) this.socket.emit(event, ...args);
|
|
200
|
+
await this.auth.ready;
|
|
201
|
+
this.socket.emit(event, ...args);
|
|
229
202
|
}
|
|
230
|
-
// ── Lifecycle
|
|
203
|
+
// ── Lifecycle ─────────────────────────────────────────────────────
|
|
231
204
|
disconnect() {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
SOCKET_CONNECTIONS.delete(`${this.url}:${this.version}`);
|
|
235
|
-
this.socket = null;
|
|
236
|
-
this.isConnected = false;
|
|
237
|
-
}
|
|
205
|
+
this.socket.disconnect();
|
|
206
|
+
this.isConnected = false;
|
|
238
207
|
}
|
|
239
208
|
async reconnect() {
|
|
240
|
-
this.
|
|
241
|
-
await this.loading;
|
|
209
|
+
this.socket.connect();
|
|
242
210
|
}
|
|
243
211
|
};
|
|
244
212
|
var SSETransport = class extends EventEmitter {
|
|
@@ -365,17 +333,9 @@ function createClient(config) {
|
|
|
365
333
|
if (config.transport && typeof config.transport === "object") {
|
|
366
334
|
transport = config.transport;
|
|
367
335
|
} else if (config.transport === "sse") {
|
|
368
|
-
transport = new SSETransport({
|
|
369
|
-
url: config.url,
|
|
370
|
-
key: config.key,
|
|
371
|
-
version
|
|
372
|
-
});
|
|
336
|
+
transport = new SSETransport({ url: config.url, version });
|
|
373
337
|
} else {
|
|
374
|
-
transport = new SocketTransport({
|
|
375
|
-
url: config.url,
|
|
376
|
-
key: config.key,
|
|
377
|
-
version
|
|
378
|
-
});
|
|
338
|
+
transport = new SocketTransport({ url: config.url, version });
|
|
379
339
|
}
|
|
380
340
|
Model.use(new FrontendAdapter(transport));
|
|
381
341
|
const client = {
|
|
@@ -399,17 +359,11 @@ function createClient(config) {
|
|
|
399
359
|
get isConnected() {
|
|
400
360
|
return transport.isConnected ?? false;
|
|
401
361
|
},
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
return
|
|
407
|
-
},
|
|
408
|
-
get authVersion() {
|
|
409
|
-
return transport.authVersion ?? 0;
|
|
410
|
-
},
|
|
411
|
-
async setKey(key) {
|
|
412
|
-
if (transport.setKey) await transport.setKey(key);
|
|
362
|
+
async authenticate(token) {
|
|
363
|
+
if (typeof transport.authenticate === "function") {
|
|
364
|
+
return transport.authenticate(token);
|
|
365
|
+
}
|
|
366
|
+
return { userId: null };
|
|
413
367
|
},
|
|
414
368
|
on(event, handler) {
|
|
415
369
|
transport.on?.(event, handler);
|
|
@@ -427,6 +381,6 @@ function createClient(config) {
|
|
|
427
381
|
return client;
|
|
428
382
|
}
|
|
429
383
|
|
|
430
|
-
export { SSETransport, SocketTransport, createClient };
|
|
431
|
-
//# sourceMappingURL=chunk-
|
|
432
|
-
//# sourceMappingURL=chunk-
|
|
384
|
+
export { AuthGate, SSETransport, SocketTransport, createClient };
|
|
385
|
+
//# sourceMappingURL=chunk-KFISHMU4.js.map
|
|
386
|
+
//# sourceMappingURL=chunk-KFISHMU4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/auth-gate.ts","../src/transports/socket.ts","../src/transports/sse.ts","../src/client.ts"],"names":["EventEmitter","body"],"mappings":"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","file":"chunk-KFISHMU4.js","sourcesContent":["/**\n * AuthGate — resettable deferred promise for authentication state.\n *\n * - resolve(): auth confirmed (authenticated or confirmed unauthenticated)\n * - reset(): back to pending (reconnect, token change)\n * - ready: awaitable promise that resolves when auth is confirmed\n */\n\nexport type AuthGateState = \"pending\" | \"ready\";\n\nexport class AuthGate {\n private _state: AuthGateState = \"pending\";\n private _resolve: (() => void) | null = null;\n private _promise: Promise<void>;\n\n constructor() {\n this._promise = this._makePending();\n }\n\n get state(): AuthGateState {\n return this._state;\n }\n\n get ready(): Promise<void> {\n return this._promise;\n }\n\n resolve(): void {\n this._state = \"ready\";\n if (this._resolve) {\n this._resolve();\n this._resolve = null;\n }\n }\n\n reset(): void {\n if (this._state === \"ready\") {\n this._state = \"pending\";\n this._promise = this._makePending();\n }\n }\n\n private _makePending(): Promise<void> {\n return new Promise<void>((r) => {\n this._resolve = r;\n });\n }\n}\n","/**\n * SocketTransport — Socket.IO transport with AuthGate.\n *\n * Connection and authentication are separate concerns:\n * - Constructor connects the socket\n * - authenticate(token) sends the token and waits for server confirmation\n * - fetch() awaits auth.ready before sending any request\n * - Disconnect resets the gate; reconnect event lets the Provider re-auth\n */\n\nimport SocketIO from \"socket.io-client\";\nimport pako from \"pako\";\nimport { decompress } from \"compress-json\";\nimport { EventEmitter } from \"eventemitter3\";\nimport ShortId from \"short-unique-id\";\nimport type { Transport } from \"@parcae/model\";\nimport { AuthGate } from \"../auth-gate\";\n\nconst uid = new ShortId({ length: 10 });\n\nexport interface SocketTransportConfig {\n url: string;\n version?: string;\n path?: string;\n}\n\nexport class SocketTransport extends EventEmitter implements Transport {\n public auth = new AuthGate();\n public isConnected = false;\n public isLoading = false;\n public userId: string | null = null;\n\n private socket: any;\n private url: string;\n private version: string;\n private inflight = new Map<string, Promise<any>>();\n\n constructor(config: SocketTransportConfig) {\n super();\n this.url = config.url;\n this.version = config.version ?? \"v1\";\n\n this.socket = SocketIO(this.url, {\n path: config.path ?? \"/ws\",\n transports: [\"websocket\"],\n withCredentials: true,\n });\n\n this.socket.on(\"connect\", () => {\n const wasConnected = this.isConnected;\n this.isConnected = true;\n this.emit(wasConnected ? \"reconnected\" : \"connected\");\n });\n\n this.socket.on(\"disconnect\", () => {\n this.isConnected = false;\n this.auth.reset();\n this.emit(\"disconnected\");\n });\n\n this.socket.on(\"error\", (err: Error) => {\n this.emit(\"error\", err);\n });\n }\n\n // ── Authenticate ──────────────────────────────────────────────────\n\n /**\n * Authenticate with the backend. Resolves the AuthGate when done.\n *\n * - token=string → send to server, wait for confirmation\n * - token=null → no auth, resolve gate immediately (unauthenticated)\n */\n async authenticate(token: string | null): Promise<{ userId: string | null }> {\n this.auth.reset();\n this.userId = null;\n\n if (!token) {\n this.auth.resolve();\n return { userId: null };\n }\n\n // Wait for socket to be connected\n if (!this.socket.connected) {\n await new Promise<void>((resolve) => {\n if (this.socket.connected) return resolve();\n this.socket.once(\"connect\", () => resolve());\n });\n }\n\n // Send token, wait for server callback\n return new Promise((resolve) => {\n this.socket.emit(\"authenticate\", token, (response: any) => {\n this.userId = response?.userId ?? null;\n this.auth.resolve();\n resolve({ userId: this.userId });\n });\n });\n }\n\n // ── Request/Response ──────────────────────────────────────────────\n\n private async fetch(\n method: string,\n path: string,\n data: any = {},\n ): Promise<any> {\n // Wait for auth to be confirmed before any request\n await this.auth.ready;\n\n // Wait for socket connection\n if (!this.socket.connected) {\n await new Promise<void>((resolve, reject) => {\n if (this.socket.connected) return resolve();\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error(\"Connection timeout\"));\n }, 30000);\n const onConnect = () => {\n cleanup();\n resolve();\n };\n const onError = (err: Error) => {\n cleanup();\n reject(err);\n };\n const cleanup = () => {\n clearTimeout(timeout);\n this.socket.off(\"connect\", onConnect);\n this.socket.off(\"connect_error\", onError);\n };\n this.socket.once(\"connect\", onConnect);\n this.socket.once(\"connect_error\", onError);\n });\n }\n\n // Deduplicate GET requests\n const upper = method.toUpperCase();\n if (upper === \"GET\") {\n const dedupeKey = `${path}:${JSON.stringify(data)}`;\n const existing = this.inflight.get(dedupeKey);\n if (existing) return existing;\n const req = this._call(method, path, data);\n this.inflight.set(dedupeKey, req);\n req.finally(() => this.inflight.delete(dedupeKey));\n return req;\n }\n\n return this._call(method, path, data);\n }\n\n private _call(method: string, path: string, data: any): Promise<any> {\n const id = uid.rnd();\n\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.socket.off(id);\n reject(new Error(`RPC timeout: ${method} ${path}`));\n }, 30000);\n\n this.socket.once(id, (msg: any) => {\n clearTimeout(timeout);\n try {\n const uncompressed = pako.ungzip(msg, { to: \"string\" });\n const parsed = decompress(JSON.parse(uncompressed));\n if (parsed.success) {\n resolve(parsed.result);\n } else {\n reject(\n new Error(\n parsed.message || parsed.error || `${method} ${path} failed`,\n ),\n );\n }\n } catch (err) {\n reject(err);\n }\n });\n\n this.socket.emit(\n \"call\",\n id,\n method.toUpperCase(),\n `/${this.version}${path}`,\n data,\n );\n });\n }\n\n async get(path: string, data?: any): Promise<any> {\n return this.fetch(\"GET\", path, data);\n }\n async post(path: string, data?: any): Promise<any> {\n return this.fetch(\"POST\", path, data);\n }\n async put(path: string, data?: any): Promise<any> {\n return this.fetch(\"PUT\", path, data);\n }\n async patch(path: string, data?: any): Promise<any> {\n return this.fetch(\"PATCH\", path, data);\n }\n async delete(path: string, data?: any): Promise<any> {\n return this.fetch(\"DELETE\", path, data);\n }\n\n // ── Subscriptions ─────────────────────────────────────────────────\n\n subscribe(event: string, handler: (...args: any[]) => void): () => void {\n this.socket.on(event, handler);\n return () => this.socket.off(event, handler);\n }\n\n unsubscribe(event: string, handler?: (...args: any[]) => void): void {\n this.socket.off(event, handler);\n }\n\n // ── Control ───────────────────────────────────────────────────────\n\n async send(event: string, ...args: any[]): Promise<void> {\n await this.auth.ready;\n this.socket.emit(event, ...args);\n }\n\n // ── Lifecycle ─────────────────────────────────────────────────────\n\n disconnect(): void {\n this.socket.disconnect();\n this.isConnected = false;\n }\n\n async reconnect(): Promise<void> {\n this.socket.connect();\n }\n}\n\nexport default SocketTransport;\n","/**\n * SSETransport — HTTP + Server-Sent Events implementation of the Transport interface.\n *\n * Request/response via standard fetch(). Subscriptions via EventSource.\n * Simpler than Socket.IO — no websocket infra needed. Good for read-heavy\n * apps, serverless backends, or environments where WebSocket isn't available.\n *\n * Trade-offs vs SocketTransport:\n * - Simpler infra (no sticky sessions, works behind any CDN/proxy)\n * - Server → client streaming only (no client → server streaming)\n * - Request/response is standard HTTP (cacheable, observable, debuggable)\n * - No compression (relies on HTTP gzip)\n * - No request deduplication (relies on HTTP/2 multiplexing)\n */\n\nimport { EventEmitter } from \"eventemitter3\";\nimport type { Transport } from \"@parcae/model\";\n\nexport interface SSETransportConfig {\n /** Base URL of the Parcae backend. */\n url: string;\n /** API key or async function returning a key. */\n key?: string | null | (() => Promise<string | null>);\n /** API version prefix. Default: \"v1\" */\n version?: string;\n}\n\nexport class SSETransport extends EventEmitter implements Transport {\n private url: string;\n private version: string;\n private apiKey: string | null | (() => Promise<string | null>);\n private key: string | null = null;\n private eventSources = new Map<string, EventSource>();\n\n public isConnected = true; // HTTP is \"always connected\"\n public isLoading = true;\n public loading: Promise<void>;\n\n constructor(config: SSETransportConfig) {\n super();\n this.url = config.url.replace(/\\/$/, \"\");\n this.version = config.version ?? \"v1\";\n this.apiKey = config.key ?? null;\n this.loading = this.resolveKey();\n }\n\n private async resolveKey(): Promise<void> {\n try {\n this.key =\n typeof this.apiKey === \"function\" ? await this.apiKey() : this.apiKey;\n this.isLoading = false;\n this.emit(\"connected\");\n } catch (err) {\n this.isLoading = false;\n this.emit(\"error\", err);\n }\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (this.key) h[\"Authorization\"] = `Bearer ${this.key}`;\n return h;\n }\n\n private fullUrl(path: string): string {\n return `${this.url}/${this.version}${path}`;\n }\n\n // ── Request/Response ──────────────────────────────────────────────────\n\n private async request(\n method: string,\n path: string,\n data?: any,\n ): Promise<any> {\n await this.loading;\n\n const isGet = method.toUpperCase() === \"GET\";\n let url = this.fullUrl(path);\n\n if (isGet && data) {\n const params = new URLSearchParams();\n for (const [k, v] of Object.entries(data)) {\n params.set(k, typeof v === \"object\" ? JSON.stringify(v) : String(v));\n }\n url += `?${params.toString()}`;\n }\n\n const res = await fetch(url, {\n method: method.toUpperCase(),\n headers: this.headers(),\n body: isGet ? undefined : JSON.stringify(data),\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: res.statusText }));\n throw new Error(body.error || body.message || `HTTP ${res.status}`);\n }\n\n const body = await res.json();\n if (body.success === false) throw new Error(body.error || \"Request failed\");\n return body.result ?? body;\n }\n\n async get(path: string, data?: any): Promise<any> {\n return this.request(\"GET\", path, data);\n }\n async post(path: string, data?: any): Promise<any> {\n return this.request(\"POST\", path, data);\n }\n async put(path: string, data?: any): Promise<any> {\n return this.request(\"PUT\", path, data);\n }\n async patch(path: string, data?: any): Promise<any> {\n return this.request(\"PATCH\", path, data);\n }\n async delete(path: string, data?: any): Promise<any> {\n return this.request(\"DELETE\", path, data);\n }\n\n // ── Subscriptions (via Server-Sent Events) ────────────────────────────\n\n subscribe(event: string, handler: (...args: any[]) => void): () => void {\n const url = `${this.url}/${this.version}/__events/${encodeURIComponent(event)}`;\n const source = new EventSource(url, { withCredentials: true });\n\n source.onmessage = (e) => {\n try {\n const data = JSON.parse(e.data);\n handler(data);\n } catch {\n handler(e.data);\n }\n };\n\n source.onerror = () => {\n // EventSource auto-reconnects\n };\n\n this.eventSources.set(event, source);\n\n return () => {\n source.close();\n this.eventSources.delete(event);\n };\n }\n\n unsubscribe(event: string): void {\n const source = this.eventSources.get(event);\n if (source) {\n source.close();\n this.eventSources.delete(event);\n }\n }\n\n // ── Control messages ──────────────────────────────────────────────────\n\n async send(event: string, ...args: any[]): Promise<void> {\n await this.request(\"POST\", \"/__control\", { event, args });\n }\n\n // ── Lifecycle ─────────────────────────────────────────────────────────\n\n disconnect(): void {\n for (const [, source] of this.eventSources) source.close();\n this.eventSources.clear();\n this.isConnected = false;\n this.emit(\"disconnected\");\n }\n\n async reconnect(): Promise<void> {\n this.loading = this.resolveKey();\n await this.loading;\n }\n}\n\nexport default SSETransport;\n","/**\n * @parcae/sdk — createClient()\n *\n * Creates a Parcae client with a pluggable transport.\n * Authentication is driven by the consumer (Provider) via client.authenticate().\n */\n\nimport { Model, FrontendAdapter } from \"@parcae/model\";\nimport type { Transport } from \"@parcae/model\";\nimport { SocketTransport } from \"./transports/socket\";\nimport { SSETransport } from \"./transports/sse\";\n\n// ─── Configuration ───────────────────────────────────────────────────────────\n\nexport interface ClientConfig {\n url: string;\n version?: string;\n transport?: \"socket\" | \"sse\" | Transport;\n}\n\nexport interface ParcaeClient {\n transport: Transport;\n get(path: string, data?: any): Promise<any>;\n post(path: string, data?: any): Promise<any>;\n put(path: string, data?: any): Promise<any>;\n patch(path: string, data?: any): Promise<any>;\n delete(path: string, data?: any): Promise<any>;\n subscribe(event: string, handler: (...args: any[]) => void): () => void;\n unsubscribe(event: string, handler?: (...args: any[]) => void): void;\n send(event: string, ...args: any[]): void;\n readonly isConnected: boolean;\n\n /** Authenticate with the backend. Resolves when auth is confirmed. */\n authenticate(token: string | null): Promise<{ userId: string | null }>;\n\n /** Listen for transport events: connected, disconnected, reconnected, error */\n on(event: string, handler: (...args: any[]) => void): void;\n off(event: string, handler?: (...args: any[]) => void): void;\n\n disconnect(): void;\n reconnect(): Promise<void>;\n}\n\n// ─── createClient ────────────────────────────────────────────────────────────\n\nexport function createClient(config: ClientConfig): ParcaeClient {\n const version = config.version ?? \"v1\";\n\n let transport: any;\n\n if (config.transport && typeof config.transport === \"object\") {\n transport = config.transport;\n } else if (config.transport === \"sse\") {\n transport = new SSETransport({ url: config.url, version });\n } else {\n transport = new SocketTransport({ url: config.url, version });\n }\n\n // Wire FrontendAdapter so Model.where() etc work\n Model.use(new FrontendAdapter(transport));\n\n const client: ParcaeClient = {\n transport,\n\n get: (path, data) => transport.get(path, data),\n post: (path, data) => transport.post(path, data),\n put: (path, data) => transport.put(path, data),\n patch: (path, data) => transport.patch(path, data),\n delete: (path, data) => transport.delete(path, data),\n\n subscribe(event, handler) {\n if (transport.subscribe) return transport.subscribe(event, handler);\n return () => {};\n },\n unsubscribe(event, handler) {\n transport.unsubscribe?.(event, handler);\n },\n send(event, ...args) {\n transport.send?.(event, ...args);\n },\n\n get isConnected() {\n return transport.isConnected ?? false;\n },\n\n async authenticate(token: string | null) {\n if (typeof transport.authenticate === \"function\") {\n return transport.authenticate(token);\n }\n // SSE/custom transports: resolve immediately\n return { userId: null };\n },\n\n on(event, handler) {\n transport.on?.(event, handler);\n },\n off(event, handler) {\n transport.off?.(event, handler);\n },\n\n disconnect() {\n transport.disconnect?.();\n },\n async reconnect() {\n await transport.reconnect?.();\n },\n };\n\n return client;\n}\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Transport } from '@parcae/model';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @parcae/sdk — createClient()
|
|
5
|
+
*
|
|
6
|
+
* Creates a Parcae client with a pluggable transport.
|
|
7
|
+
* Authentication is driven by the consumer (Provider) via client.authenticate().
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
interface ClientConfig {
|
|
11
|
+
url: string;
|
|
12
|
+
version?: string;
|
|
13
|
+
transport?: "socket" | "sse" | Transport;
|
|
14
|
+
}
|
|
15
|
+
interface ParcaeClient {
|
|
16
|
+
transport: Transport;
|
|
17
|
+
get(path: string, data?: any): Promise<any>;
|
|
18
|
+
post(path: string, data?: any): Promise<any>;
|
|
19
|
+
put(path: string, data?: any): Promise<any>;
|
|
20
|
+
patch(path: string, data?: any): Promise<any>;
|
|
21
|
+
delete(path: string, data?: any): Promise<any>;
|
|
22
|
+
subscribe(event: string, handler: (...args: any[]) => void): () => void;
|
|
23
|
+
unsubscribe(event: string, handler?: (...args: any[]) => void): void;
|
|
24
|
+
send(event: string, ...args: any[]): void;
|
|
25
|
+
readonly isConnected: boolean;
|
|
26
|
+
/** Authenticate with the backend. Resolves when auth is confirmed. */
|
|
27
|
+
authenticate(token: string | null): Promise<{
|
|
28
|
+
userId: string | null;
|
|
29
|
+
}>;
|
|
30
|
+
/** Listen for transport events: connected, disconnected, reconnected, error */
|
|
31
|
+
on(event: string, handler: (...args: any[]) => void): void;
|
|
32
|
+
off(event: string, handler?: (...args: any[]) => void): void;
|
|
33
|
+
disconnect(): void;
|
|
34
|
+
reconnect(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
declare function createClient(config: ClientConfig): ParcaeClient;
|
|
37
|
+
|
|
38
|
+
export { type ClientConfig as C, type ParcaeClient as P, createClient as c };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,46 +1,64 @@
|
|
|
1
|
-
export { C as ClientConfig, P as ParcaeClient, c as createClient } from './client-
|
|
1
|
+
export { C as ClientConfig, P as ParcaeClient, c as createClient } from './client-CeIUZzoo.js';
|
|
2
2
|
import { EventEmitter } from 'eventemitter3';
|
|
3
3
|
import { Transport } from '@parcae/model';
|
|
4
4
|
export { FrontendAdapter, Model, Transport } from '@parcae/model';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* AuthGate — resettable deferred promise for authentication state.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
* (
|
|
9
|
+
* - resolve(): auth confirmed (authenticated or confirmed unauthenticated)
|
|
10
|
+
* - reset(): back to pending (reconnect, token change)
|
|
11
|
+
* - ready: awaitable promise that resolves when auth is confirmed
|
|
12
|
+
*/
|
|
13
|
+
type AuthGateState = "pending" | "ready";
|
|
14
|
+
declare class AuthGate {
|
|
15
|
+
private _state;
|
|
16
|
+
private _resolve;
|
|
17
|
+
private _promise;
|
|
18
|
+
constructor();
|
|
19
|
+
get state(): AuthGateState;
|
|
20
|
+
get ready(): Promise<void>;
|
|
21
|
+
resolve(): void;
|
|
22
|
+
reset(): void;
|
|
23
|
+
private _makePending;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* SocketTransport — Socket.IO transport with AuthGate.
|
|
11
28
|
*
|
|
12
|
-
*
|
|
29
|
+
* Connection and authentication are separate concerns:
|
|
30
|
+
* - Constructor connects the socket
|
|
31
|
+
* - authenticate(token) sends the token and waits for server confirmation
|
|
32
|
+
* - fetch() awaits auth.ready before sending any request
|
|
33
|
+
* - Disconnect resets the gate; reconnect event lets the Provider re-auth
|
|
13
34
|
*/
|
|
14
35
|
|
|
15
36
|
interface SocketTransportConfig {
|
|
16
37
|
url: string;
|
|
17
|
-
key?: string | null | (() => Promise<string | null>);
|
|
18
38
|
version?: string;
|
|
19
|
-
/** Socket.IO path. Default: "/ws" */
|
|
20
39
|
path?: string;
|
|
21
40
|
}
|
|
22
41
|
declare class SocketTransport extends EventEmitter implements Transport {
|
|
42
|
+
auth: AuthGate;
|
|
43
|
+
isConnected: boolean;
|
|
44
|
+
isLoading: boolean;
|
|
45
|
+
userId: string | null;
|
|
23
46
|
private socket;
|
|
24
|
-
private pendingHandlers;
|
|
25
|
-
private apiKey;
|
|
26
|
-
private key;
|
|
27
47
|
private url;
|
|
28
48
|
private version;
|
|
29
|
-
private socketPath;
|
|
30
|
-
private waitForAuth;
|
|
31
|
-
private resolveAuth;
|
|
32
49
|
private inflight;
|
|
33
|
-
loading: Promise<void>;
|
|
34
|
-
isLoading: boolean;
|
|
35
|
-
isConnected: boolean;
|
|
36
|
-
isConnecting: boolean;
|
|
37
|
-
authVersion: number;
|
|
38
50
|
constructor(config: SocketTransportConfig);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Authenticate with the backend. Resolves the AuthGate when done.
|
|
53
|
+
*
|
|
54
|
+
* - token=string → send to server, wait for confirmation
|
|
55
|
+
* - token=null → no auth, resolve gate immediately (unauthenticated)
|
|
56
|
+
*/
|
|
57
|
+
authenticate(token: string | null): Promise<{
|
|
58
|
+
userId: string | null;
|
|
59
|
+
}>;
|
|
42
60
|
private fetch;
|
|
43
|
-
private
|
|
61
|
+
private _call;
|
|
44
62
|
get(path: string, data?: any): Promise<any>;
|
|
45
63
|
post(path: string, data?: any): Promise<any>;
|
|
46
64
|
put(path: string, data?: any): Promise<any>;
|
|
@@ -102,4 +120,4 @@ declare class SSETransport extends EventEmitter implements Transport {
|
|
|
102
120
|
reconnect(): Promise<void>;
|
|
103
121
|
}
|
|
104
122
|
|
|
105
|
-
export { SSETransport, type SSETransportConfig, SocketTransport, type SocketTransportConfig };
|
|
123
|
+
export { AuthGate, type AuthGateState, SSETransport, type SSETransportConfig, SocketTransport, type SocketTransportConfig };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { SSETransport, SocketTransport, createClient } from './chunk-
|
|
1
|
+
export { AuthGate, SSETransport, SocketTransport, createClient } from './chunk-KFISHMU4.js';
|
|
2
2
|
export { FrontendAdapter, Model } from '@parcae/model';
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default from 'react';
|
|
3
|
-
import { P as ParcaeClient, C as ClientConfig } from '../client-
|
|
3
|
+
import { P as ParcaeClient, C as ClientConfig } from '../client-CeIUZzoo.js';
|
|
4
4
|
import '@parcae/model';
|
|
5
5
|
|
|
6
6
|
interface ParcaeProviderProps {
|
|
7
|
-
/** Pre-created client instance. If provided, url/key/transport are ignored. */
|
|
8
7
|
client?: ParcaeClient;
|
|
9
|
-
/** API base URL (required if no client provided). */
|
|
10
8
|
url?: string;
|
|
11
|
-
/**
|
|
9
|
+
/** undefined = auth loading, null = no session, string = token */
|
|
12
10
|
apiKey?: string | null | undefined;
|
|
13
|
-
/** Stable user ID — triggers re-auth when it changes. */
|
|
14
11
|
userId?: string | null;
|
|
15
|
-
/** API version. Default: "v1" */
|
|
16
12
|
version?: string;
|
|
17
|
-
/** Transport type. Default: "socket" */
|
|
18
13
|
transport?: ClientConfig["transport"];
|
|
19
14
|
children: React__default.ReactNode;
|
|
20
15
|
onReady?: (client: ParcaeClient) => void;
|
|
@@ -56,21 +51,11 @@ declare function useApi(): {
|
|
|
56
51
|
patch: (path: string, data?: any) => Promise<any>;
|
|
57
52
|
delete: (path: string, data?: any) => Promise<any>;
|
|
58
53
|
};
|
|
59
|
-
/**
|
|
60
|
-
* useSDK — raw client instance.
|
|
61
|
-
*/
|
|
62
54
|
declare function useSDK(): ParcaeClient;
|
|
63
|
-
/**
|
|
64
|
-
* useConnectionStatus — connection + auth state.
|
|
65
|
-
*/
|
|
66
55
|
declare function useConnectionStatus(): {
|
|
67
56
|
isConnected: boolean;
|
|
68
|
-
isLoading: boolean;
|
|
69
57
|
authState: AuthState;
|
|
70
58
|
};
|
|
71
|
-
/**
|
|
72
|
-
* useAuthState — just the auth state.
|
|
73
|
-
*/
|
|
74
59
|
declare function useAuthState(): AuthState;
|
|
75
60
|
|
|
76
61
|
declare function useSetting<T = string>(key: string, defaultValue: T): [T, (value: T) => Promise<void>, {
|
package/dist/react/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createClient } from '../chunk-
|
|
1
|
+
import { createClient } from '../chunk-KFISHMU4.js';
|
|
2
2
|
import { createContext, useContext, useState, useMemo, useRef, useEffect, useSyncExternalStore, useCallback } from 'react';
|
|
3
3
|
import { jsx } from 'react/jsx-runtime';
|
|
4
4
|
|
|
@@ -22,9 +22,6 @@ var ParcaeProvider = ({
|
|
|
22
22
|
onError
|
|
23
23
|
}) => {
|
|
24
24
|
const [authState, setAuthState] = useState(
|
|
25
|
-
// If apiKey is undefined, the frontend auth provider is still loading.
|
|
26
|
-
// If apiKey is null, the user is not logged in.
|
|
27
|
-
// If apiKey is a string, we have a token but haven't verified it yet.
|
|
28
25
|
apiKey === void 0 ? "loading" : apiKey === null ? "unauthenticated" : "loading"
|
|
29
26
|
);
|
|
30
27
|
const [authVersion, setAuthVersion] = useState(0);
|
|
@@ -34,8 +31,10 @@ var ParcaeProvider = ({
|
|
|
34
31
|
throw new Error(
|
|
35
32
|
"ParcaeProvider requires either a `client` prop or a `url` prop"
|
|
36
33
|
);
|
|
37
|
-
return createClient({ url, version, transport
|
|
34
|
+
return createClient({ url, version, transport });
|
|
38
35
|
}, [externalClient, url, version, transport]);
|
|
36
|
+
const apiKeyRef = useRef(apiKey);
|
|
37
|
+
apiKeyRef.current = apiKey;
|
|
39
38
|
const onReadyRef = useRef(onReady);
|
|
40
39
|
onReadyRef.current = onReady;
|
|
41
40
|
const onErrorRef = useRef(onError);
|
|
@@ -45,14 +44,9 @@ var ParcaeProvider = ({
|
|
|
45
44
|
setAuthState("loading");
|
|
46
45
|
return;
|
|
47
46
|
}
|
|
48
|
-
if (apiKey === null) {
|
|
49
|
-
setAuthState("unauthenticated");
|
|
50
|
-
setAuthVersion((v) => v + 1);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
47
|
setAuthState("loading");
|
|
54
|
-
client.
|
|
55
|
-
setAuthState("authenticated");
|
|
48
|
+
client.authenticate(apiKey).then(({ userId: uid }) => {
|
|
49
|
+
setAuthState(uid ? "authenticated" : "unauthenticated");
|
|
56
50
|
setAuthVersion((v) => v + 1);
|
|
57
51
|
onReadyRef.current?.(client);
|
|
58
52
|
}).catch((err) => {
|
|
@@ -61,6 +55,24 @@ var ParcaeProvider = ({
|
|
|
61
55
|
onErrorRef.current?.(err);
|
|
62
56
|
});
|
|
63
57
|
}, [apiKey, userId, client]);
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
const onReconnect = () => {
|
|
60
|
+
const key = apiKeyRef.current;
|
|
61
|
+
if (key === void 0) return;
|
|
62
|
+
setAuthState("loading");
|
|
63
|
+
client.authenticate(key).then(({ userId: uid }) => {
|
|
64
|
+
setAuthState(uid ? "authenticated" : "unauthenticated");
|
|
65
|
+
setAuthVersion((v) => v + 1);
|
|
66
|
+
}).catch(() => {
|
|
67
|
+
setAuthState("unauthenticated");
|
|
68
|
+
setAuthVersion((v) => v + 1);
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
client.on("reconnected", onReconnect);
|
|
72
|
+
return () => {
|
|
73
|
+
client.off("reconnected", onReconnect);
|
|
74
|
+
};
|
|
75
|
+
}, [client]);
|
|
64
76
|
useEffect(() => {
|
|
65
77
|
const onErr = (err) => onErrorRef.current?.(err);
|
|
66
78
|
client.on("error", onErr);
|
|
@@ -224,11 +236,7 @@ function useSDK() {
|
|
|
224
236
|
}
|
|
225
237
|
function useConnectionStatus() {
|
|
226
238
|
const { client, authState } = useParcae();
|
|
227
|
-
return {
|
|
228
|
-
isConnected: client.isConnected,
|
|
229
|
-
isLoading: client.isLoading,
|
|
230
|
-
authState
|
|
231
|
-
};
|
|
239
|
+
return { isConnected: client.isConnected, authState };
|
|
232
240
|
}
|
|
233
241
|
function useAuthState() {
|
|
234
242
|
return useParcae().authState;
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/context.ts","../../src/react/Provider.tsx","../../src/react/useQuery.ts","../../src/react/useApi.ts","../../src/react/useSetting.ts"],"names":["useRef","useEffect","entry","useMemo","useState","useCallback"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { ParcaeClient } from \"../client\";\n\nexport type AuthState = \"loading\" | \"authenticated\" | \"unauthenticated\";\n\nexport interface ParcaeContextValue {\n client: ParcaeClient;\n authState: AuthState;\n authVersion: number;\n}\n\nexport const ParcaeContext = createContext<ParcaeContextValue | null>(null);\n\nexport function useParcae(): ParcaeContextValue {\n const ctx = useContext(ParcaeContext);\n if (!ctx) {\n throw new Error(\"useParcae must be used within a <ParcaeProvider>\");\n }\n return ctx;\n}\n","\"use client\";\n\nimport React, {\n useEffect,\n useMemo,\n useRef,\n useState,\n useCallback,\n} from \"react\";\nimport { createClient } from \"../client\";\nimport type { ParcaeClient, ClientConfig } from \"../client\";\nimport { ParcaeContext } from \"./context\";\nimport type { ParcaeContextValue, AuthState } from \"./context\";\n\nexport interface ParcaeProviderProps {\n /** Pre-created client instance. If provided, url/key/transport are ignored. */\n client?: ParcaeClient;\n /** API base URL (required if no client provided). */\n url?: string;\n /** Bearer token, null (no session), or undefined (still loading). */\n apiKey?: string | null | undefined;\n /** Stable user ID — triggers re-auth when it changes. */\n userId?: string | null;\n /** API version. Default: \"v1\" */\n version?: string;\n /** Transport type. Default: \"socket\" */\n transport?: ClientConfig[\"transport\"];\n children: React.ReactNode;\n onReady?: (client: ParcaeClient) => void;\n onError?: (error: Error) => void;\n}\n\nexport const ParcaeProvider: React.FC<ParcaeProviderProps> = ({\n client: externalClient,\n url,\n apiKey,\n userId,\n version = \"v1\",\n transport = \"socket\",\n children,\n onReady,\n onError,\n}) => {\n const [authState, setAuthState] = useState<AuthState>(\n // If apiKey is undefined, the frontend auth provider is still loading.\n // If apiKey is null, the user is not logged in.\n // If apiKey is a string, we have a token but haven't verified it yet.\n apiKey === undefined\n ? \"loading\"\n : apiKey === null\n ? \"unauthenticated\"\n : \"loading\",\n );\n const [authVersion, setAuthVersion] = useState(0);\n\n const client = useMemo(() => {\n if (externalClient) return externalClient;\n if (!url)\n throw new Error(\n \"ParcaeProvider requires either a `client` prop or a `url` prop\",\n );\n return createClient({ url, version, transport, key: null });\n }, [externalClient, url, version, transport]);\n\n const onReadyRef = useRef(onReady);\n onReadyRef.current = onReady;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n // Authenticate when apiKey changes\n useEffect(() => {\n // apiKey is undefined → frontend auth still loading, do nothing\n if (apiKey === undefined) {\n setAuthState(\"loading\");\n return;\n }\n\n // apiKey is null → user is not logged in\n if (apiKey === null) {\n setAuthState(\"unauthenticated\");\n setAuthVersion((v) => v + 1);\n return;\n }\n\n // apiKey is a string → send to backend for verification\n setAuthState(\"loading\");\n client\n .setKey(apiKey)\n .then(() => {\n setAuthState(\"authenticated\");\n setAuthVersion((v) => v + 1);\n onReadyRef.current?.(client);\n })\n .catch((err) => {\n setAuthState(\"unauthenticated\");\n setAuthVersion((v) => v + 1);\n onErrorRef.current?.(err);\n });\n }, [apiKey, userId, client]);\n\n useEffect(() => {\n const onErr = (err: Error) => onErrorRef.current?.(err);\n client.on(\"error\", onErr);\n return () => {\n client.off(\"error\", onErr);\n };\n }, [client]);\n\n const contextValue = useMemo<ParcaeContextValue>(\n () => ({ client, authState, authVersion }),\n [client, authState, authVersion],\n );\n\n return (\n <ParcaeContext.Provider value={contextValue}>\n {children}\n </ParcaeContext.Provider>\n );\n};\n\nexport default ParcaeProvider;\n","\"use client\";\n\n/**\n * useQuery — calls chain.find() via socket RPC, subscribes to diffs automatically.\n *\n * No separate subscribe:query event. The server auto-subscribes when you\n * query a list endpoint. Diffs arrive on the same query key.\n */\n\nimport { useEffect, useRef, useSyncExternalStore } from \"react\";\nimport { useParcae } from \"./context\";\nimport type { ParcaeClient } from \"../client\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\ninterface QueryChain<T> {\n find(): Promise<T[]>;\n __steps?: any[];\n __modelType?: string;\n __modelClass?: any;\n __adapter?: any;\n}\n\ninterface UseQueryOptions {\n waitForAuth?: boolean;\n}\n\ninterface UseQueryResult<T> {\n items: T[];\n loading: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\n// ─── External Cache ──────────────────────────────────────────────────────────\n\ninterface CacheEntry {\n items: any[];\n loading: boolean;\n error: Error | null;\n refs: number;\n listeners: Set<() => void>;\n dispose: (() => void) | null;\n gcTimer: ReturnType<typeof setTimeout> | null;\n}\n\nconst cache = new Map<string, CacheEntry>();\nconst GC_DELAY = 60_000;\nconst EMPTY: any[] = [];\n\nfunction getOrCreate(key: string): CacheEntry {\n let e = cache.get(key);\n if (!e) {\n e = {\n items: EMPTY,\n loading: true,\n error: null,\n refs: 0,\n listeners: new Set(),\n dispose: null,\n gcTimer: null,\n };\n cache.set(key, e);\n }\n return e;\n}\n\nfunction notify(e: CacheEntry): void {\n for (const fn of e.listeners) fn();\n}\n\n// ─── Fetch via chain.find() ──────────────────────────────────────────────────\n\nfunction doFetch(\n key: string,\n entry: CacheEntry,\n chain: QueryChain<any>,\n client: ParcaeClient,\n): void {\n entry.loading = true;\n entry.error = null;\n notify(entry);\n\n chain\n .find()\n .then((result: any[]) => {\n entry.items = result;\n entry.loading = false;\n notify(entry);\n })\n .catch((err: Error) => {\n entry.error = err;\n entry.loading = false;\n notify(entry);\n });\n\n // Listen for realtime diffs (server auto-subscribes on the call)\n if (!entry.dispose && chain.__modelType) {\n const diffEvent = `query:diff:${key}`;\n\n const unsub = client.subscribe(diffEvent, (ops: any[]) => {\n if (!ops?.length) return;\n\n const map = new Map(entry.items.map((i: any) => [i.id, i]));\n let changed = false;\n\n for (const op of ops) {\n if (\n op.op === \"add\" &&\n !map.has(op.id) &&\n op.data &&\n chain.__modelClass\n ) {\n map.set(op.id, new chain.__modelClass(chain.__adapter, op.data));\n changed = true;\n } else if (op.op === \"remove\" && map.has(op.id)) {\n map.delete(op.id);\n changed = true;\n } else if (op.op === \"update\" && map.has(op.id) && op.data) {\n const existing = map.get(op.id);\n for (const [k, v] of Object.entries(op.data))\n (existing as any)[k] = v;\n changed = true;\n }\n }\n\n if (changed) {\n entry.items = [...map.values()];\n notify(entry);\n }\n });\n\n entry.dispose = () => {\n unsub();\n entry.dispose = null;\n };\n }\n}\n\n// ─── useQuery ────────────────────────────────────────────────────────────────\n\nexport function useQuery<T>(\n chain: QueryChain<T> | null | undefined,\n options: UseQueryOptions = {},\n): UseQueryResult<T> {\n const { client, authState, authVersion } = useParcae();\n const waitForAuth = options.waitForAuth ?? true;\n const authReady = !waitForAuth || authState !== \"loading\";\n\n const key =\n chain && authReady\n ? `${chain.__modelType}:${authVersion}:${JSON.stringify(chain.__steps ?? [])}`\n : null;\n\n const keyRef = useRef(key);\n keyRef.current = key;\n\n const subscribe = (onChange: () => void) => {\n const k = keyRef.current;\n if (!k) return () => {};\n const e = getOrCreate(k);\n e.refs++;\n e.listeners.add(onChange);\n if (e.gcTimer) {\n clearTimeout(e.gcTimer);\n e.gcTimer = null;\n }\n return () => {\n e.listeners.delete(onChange);\n e.refs--;\n if (e.refs <= 0) {\n e.gcTimer = setTimeout(() => {\n e.dispose?.();\n cache.delete(k);\n }, GC_DELAY);\n }\n };\n };\n\n const getSnapshot = (): any[] => {\n const k = keyRef.current;\n if (!k) return EMPTY;\n return cache.get(k)?.items ?? EMPTY;\n };\n\n const items = useSyncExternalStore(\n subscribe,\n getSnapshot,\n getSnapshot,\n ) as T[];\n\n useEffect(() => {\n if (!key || !chain) return;\n const entry = getOrCreate(key);\n if (entry.items === EMPTY) {\n doFetch(key, entry, chain, client);\n }\n }, [key]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const refetch = () => {\n if (!key || !chain) return;\n doFetch(key, getOrCreate(key), chain, client);\n };\n\n if (!key)\n return {\n items: EMPTY as T[],\n loading: !authReady,\n error: null,\n refetch: () => {},\n };\n\n const entry = cache.get(key);\n return {\n items,\n loading: entry?.loading ?? true,\n error: entry?.error ?? null,\n refetch,\n };\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport { useParcae } from \"./context\";\n\nexport function useApi() {\n const { client } = useParcae();\n\n return useMemo(\n () => ({\n get: client.get.bind(client),\n post: client.post.bind(client),\n put: client.put.bind(client),\n patch: client.patch.bind(client),\n delete: client.delete.bind(client),\n }),\n [client],\n );\n}\n\n/**\n * useSDK — raw client instance.\n */\nexport function useSDK() {\n return useParcae().client;\n}\n\n/**\n * useConnectionStatus — connection + auth state.\n */\nexport function useConnectionStatus() {\n const { client, authState } = useParcae();\n return {\n isConnected: client.isConnected,\n isLoading: client.isLoading,\n authState,\n };\n}\n\n/**\n * useAuthState — just the auth state.\n */\nexport function useAuthState() {\n return useParcae().authState;\n}\n","\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport { useParcae } from \"./context\";\n\nexport function useSetting<T = string>(\n key: string,\n defaultValue: T,\n): [T, (value: T) => Promise<void>, { isLoading: boolean }] {\n const { client, authState } = useParcae();\n const [value, setValue] = useState<T>(defaultValue);\n const [isLoading, setIsLoading] = useState(true);\n\n // Wait for auth before fetching settings (they're user-scoped)\n useEffect(() => {\n if (authState === \"loading\") return;\n if (authState === \"unauthenticated\") {\n setIsLoading(false);\n return;\n }\n\n let cancelled = false;\n\n client\n .get(`/settings/${encodeURIComponent(key)}`)\n .then((result) => {\n if (!cancelled && result?.value !== undefined) {\n setValue(result.value);\n }\n })\n .catch(() => {})\n .finally(() => {\n if (!cancelled) setIsLoading(false);\n });\n\n return () => {\n cancelled = true;\n };\n }, [key, client, authState]);\n\n const update = useCallback(\n async (newValue: T) => {\n setValue(newValue);\n await client.put(`/settings/${encodeURIComponent(key)}`, {\n value: newValue,\n });\n },\n [key, client],\n );\n\n return [value, update, { isLoading }];\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/react/context.ts","../../src/react/Provider.tsx","../../src/react/useQuery.ts","../../src/react/useApi.ts","../../src/react/useSetting.ts"],"names":["useRef","useEffect","entry","useMemo","useState"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { ParcaeClient } from \"../client\";\n\nexport type AuthState = \"loading\" | \"authenticated\" | \"unauthenticated\";\n\nexport interface ParcaeContextValue {\n client: ParcaeClient;\n authState: AuthState;\n authVersion: number;\n}\n\nexport const ParcaeContext = createContext<ParcaeContextValue | null>(null);\n\nexport function useParcae(): ParcaeContextValue {\n const ctx = useContext(ParcaeContext);\n if (!ctx) {\n throw new Error(\"useParcae must be used within a <ParcaeProvider>\");\n }\n return ctx;\n}\n","\"use client\";\n\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { createClient } from \"../client\";\nimport type { ParcaeClient, ClientConfig } from \"../client\";\nimport { ParcaeContext } from \"./context\";\nimport type { AuthState } from \"./context\";\n\nexport interface ParcaeProviderProps {\n client?: ParcaeClient;\n url?: string;\n /** undefined = auth loading, null = no session, string = token */\n apiKey?: string | null | undefined;\n userId?: string | null;\n version?: string;\n transport?: ClientConfig[\"transport\"];\n children: React.ReactNode;\n onReady?: (client: ParcaeClient) => void;\n onError?: (error: Error) => void;\n}\n\nexport const ParcaeProvider: React.FC<ParcaeProviderProps> = ({\n client: externalClient,\n url,\n apiKey,\n userId,\n version = \"v1\",\n transport = \"socket\",\n children,\n onReady,\n onError,\n}) => {\n const [authState, setAuthState] = useState<AuthState>(\n apiKey === undefined\n ? \"loading\"\n : apiKey === null\n ? \"unauthenticated\"\n : \"loading\",\n );\n const [authVersion, setAuthVersion] = useState(0);\n\n const client = useMemo(() => {\n if (externalClient) return externalClient;\n if (!url)\n throw new Error(\n \"ParcaeProvider requires either a `client` prop or a `url` prop\",\n );\n return createClient({ url, version, transport });\n }, [externalClient, url, version, transport]);\n\n const apiKeyRef = useRef(apiKey);\n apiKeyRef.current = apiKey;\n const onReadyRef = useRef(onReady);\n onReadyRef.current = onReady;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n // Authenticate when apiKey changes\n useEffect(() => {\n if (apiKey === undefined) {\n setAuthState(\"loading\");\n return;\n }\n\n setAuthState(\"loading\");\n client\n .authenticate(apiKey)\n .then(({ userId: uid }) => {\n setAuthState(uid ? \"authenticated\" : \"unauthenticated\");\n setAuthVersion((v) => v + 1);\n onReadyRef.current?.(client);\n })\n .catch((err: Error) => {\n setAuthState(\"unauthenticated\");\n setAuthVersion((v) => v + 1);\n onErrorRef.current?.(err);\n });\n }, [apiKey, userId, client]);\n\n // Re-authenticate on reconnect\n useEffect(() => {\n const onReconnect = () => {\n const key = apiKeyRef.current;\n if (key === undefined) return;\n\n setAuthState(\"loading\");\n client\n .authenticate(key)\n .then(({ userId: uid }) => {\n setAuthState(uid ? \"authenticated\" : \"unauthenticated\");\n setAuthVersion((v) => v + 1);\n })\n .catch(() => {\n setAuthState(\"unauthenticated\");\n setAuthVersion((v) => v + 1);\n });\n };\n\n client.on(\"reconnected\", onReconnect);\n return () => {\n client.off(\"reconnected\", onReconnect);\n };\n }, [client]);\n\n // Forward errors\n useEffect(() => {\n const onErr = (err: Error) => onErrorRef.current?.(err);\n client.on(\"error\", onErr);\n return () => {\n client.off(\"error\", onErr);\n };\n }, [client]);\n\n const contextValue = useMemo(\n () => ({ client, authState, authVersion }),\n [client, authState, authVersion],\n );\n\n return (\n <ParcaeContext.Provider value={contextValue}>\n {children}\n </ParcaeContext.Provider>\n );\n};\n\nexport default ParcaeProvider;\n","\"use client\";\n\n/**\n * useQuery — calls chain.find() via socket RPC, subscribes to diffs automatically.\n *\n * No separate subscribe:query event. The server auto-subscribes when you\n * query a list endpoint. Diffs arrive on the same query key.\n */\n\nimport { useEffect, useRef, useSyncExternalStore } from \"react\";\nimport { useParcae } from \"./context\";\nimport type { ParcaeClient } from \"../client\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\ninterface QueryChain<T> {\n find(): Promise<T[]>;\n __steps?: any[];\n __modelType?: string;\n __modelClass?: any;\n __adapter?: any;\n}\n\ninterface UseQueryOptions {\n waitForAuth?: boolean;\n}\n\ninterface UseQueryResult<T> {\n items: T[];\n loading: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\n// ─── External Cache ──────────────────────────────────────────────────────────\n\ninterface CacheEntry {\n items: any[];\n loading: boolean;\n error: Error | null;\n refs: number;\n listeners: Set<() => void>;\n dispose: (() => void) | null;\n gcTimer: ReturnType<typeof setTimeout> | null;\n}\n\nconst cache = new Map<string, CacheEntry>();\nconst GC_DELAY = 60_000;\nconst EMPTY: any[] = [];\n\nfunction getOrCreate(key: string): CacheEntry {\n let e = cache.get(key);\n if (!e) {\n e = {\n items: EMPTY,\n loading: true,\n error: null,\n refs: 0,\n listeners: new Set(),\n dispose: null,\n gcTimer: null,\n };\n cache.set(key, e);\n }\n return e;\n}\n\nfunction notify(e: CacheEntry): void {\n for (const fn of e.listeners) fn();\n}\n\n// ─── Fetch via chain.find() ──────────────────────────────────────────────────\n\nfunction doFetch(\n key: string,\n entry: CacheEntry,\n chain: QueryChain<any>,\n client: ParcaeClient,\n): void {\n entry.loading = true;\n entry.error = null;\n notify(entry);\n\n chain\n .find()\n .then((result: any[]) => {\n entry.items = result;\n entry.loading = false;\n notify(entry);\n })\n .catch((err: Error) => {\n entry.error = err;\n entry.loading = false;\n notify(entry);\n });\n\n // Listen for realtime diffs (server auto-subscribes on the call)\n if (!entry.dispose && chain.__modelType) {\n const diffEvent = `query:diff:${key}`;\n\n const unsub = client.subscribe(diffEvent, (ops: any[]) => {\n if (!ops?.length) return;\n\n const map = new Map(entry.items.map((i: any) => [i.id, i]));\n let changed = false;\n\n for (const op of ops) {\n if (\n op.op === \"add\" &&\n !map.has(op.id) &&\n op.data &&\n chain.__modelClass\n ) {\n map.set(op.id, new chain.__modelClass(chain.__adapter, op.data));\n changed = true;\n } else if (op.op === \"remove\" && map.has(op.id)) {\n map.delete(op.id);\n changed = true;\n } else if (op.op === \"update\" && map.has(op.id) && op.data) {\n const existing = map.get(op.id);\n for (const [k, v] of Object.entries(op.data))\n (existing as any)[k] = v;\n changed = true;\n }\n }\n\n if (changed) {\n entry.items = [...map.values()];\n notify(entry);\n }\n });\n\n entry.dispose = () => {\n unsub();\n entry.dispose = null;\n };\n }\n}\n\n// ─── useQuery ────────────────────────────────────────────────────────────────\n\nexport function useQuery<T>(\n chain: QueryChain<T> | null | undefined,\n options: UseQueryOptions = {},\n): UseQueryResult<T> {\n const { client, authState, authVersion } = useParcae();\n const waitForAuth = options.waitForAuth ?? true;\n const authReady = !waitForAuth || authState !== \"loading\";\n\n const key =\n chain && authReady\n ? `${chain.__modelType}:${authVersion}:${JSON.stringify(chain.__steps ?? [])}`\n : null;\n\n const keyRef = useRef(key);\n keyRef.current = key;\n\n const subscribe = (onChange: () => void) => {\n const k = keyRef.current;\n if (!k) return () => {};\n const e = getOrCreate(k);\n e.refs++;\n e.listeners.add(onChange);\n if (e.gcTimer) {\n clearTimeout(e.gcTimer);\n e.gcTimer = null;\n }\n return () => {\n e.listeners.delete(onChange);\n e.refs--;\n if (e.refs <= 0) {\n e.gcTimer = setTimeout(() => {\n e.dispose?.();\n cache.delete(k);\n }, GC_DELAY);\n }\n };\n };\n\n const getSnapshot = (): any[] => {\n const k = keyRef.current;\n if (!k) return EMPTY;\n return cache.get(k)?.items ?? EMPTY;\n };\n\n const items = useSyncExternalStore(\n subscribe,\n getSnapshot,\n getSnapshot,\n ) as T[];\n\n useEffect(() => {\n if (!key || !chain) return;\n const entry = getOrCreate(key);\n if (entry.items === EMPTY) {\n doFetch(key, entry, chain, client);\n }\n }, [key]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const refetch = () => {\n if (!key || !chain) return;\n doFetch(key, getOrCreate(key), chain, client);\n };\n\n if (!key)\n return {\n items: EMPTY as T[],\n loading: !authReady,\n error: null,\n refetch: () => {},\n };\n\n const entry = cache.get(key);\n return {\n items,\n loading: entry?.loading ?? true,\n error: entry?.error ?? null,\n refetch,\n };\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport { useParcae } from \"./context\";\n\nexport function useApi() {\n const { client } = useParcae();\n return useMemo(\n () => ({\n get: client.get.bind(client),\n post: client.post.bind(client),\n put: client.put.bind(client),\n patch: client.patch.bind(client),\n delete: client.delete.bind(client),\n }),\n [client],\n );\n}\n\nexport function useSDK() {\n return useParcae().client;\n}\n\nexport function useConnectionStatus() {\n const { client, authState } = useParcae();\n return { isConnected: client.isConnected, authState };\n}\n\nexport function useAuthState() {\n return useParcae().authState;\n}\n","\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport { useParcae } from \"./context\";\n\nexport function useSetting<T = string>(\n key: string,\n defaultValue: T,\n): [T, (value: T) => Promise<void>, { isLoading: boolean }] {\n const { client, authState } = useParcae();\n const [value, setValue] = useState<T>(defaultValue);\n const [isLoading, setIsLoading] = useState(true);\n\n // Wait for auth before fetching settings (they're user-scoped)\n useEffect(() => {\n if (authState === \"loading\") return;\n if (authState === \"unauthenticated\") {\n setIsLoading(false);\n return;\n }\n\n let cancelled = false;\n\n client\n .get(`/settings/${encodeURIComponent(key)}`)\n .then((result) => {\n if (!cancelled && result?.value !== undefined) {\n setValue(result.value);\n }\n })\n .catch(() => {})\n .finally(() => {\n if (!cancelled) setIsLoading(false);\n });\n\n return () => {\n cancelled = true;\n };\n }, [key, client, authState]);\n\n const update = useCallback(\n async (newValue: T) => {\n setValue(newValue);\n await client.put(`/settings/${encodeURIComponent(key)}`, {\n value: newValue,\n });\n },\n [key, client],\n );\n\n return [value, update, { isLoading }];\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/transports/socket.ts","../src/transports/sse.ts","../src/client.ts"],"names":["EventEmitter","body"],"mappings":"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","file":"chunk-IETH2XOR.js","sourcesContent":["/**\n * SocketTransport — Socket.IO implementation of the Transport interface.\n *\n * Bidirectional, full-duplex. Best for apps that need realtime subscriptions\n * (live query updates, collaborative editing, chat, etc.).\n *\n * Extracted from Dollhouse Studio's Dollhouse.ts (667 lines).\n */\n\nimport SocketIO from \"socket.io-client\";\nimport pako from \"pako\";\nimport { decompress } from \"compress-json\";\nimport { EventEmitter } from \"eventemitter3\";\nimport ShortId from \"short-unique-id\";\nimport type { Transport } from \"@parcae/model\";\n\nconst uid = new ShortId({ length: 10 });\nconst SOCKET_CONNECTIONS = new Map<string, any>();\n\nexport interface SocketTransportConfig {\n url: string;\n key?: string | null | (() => Promise<string | null>);\n version?: string;\n /** Socket.IO path. Default: \"/ws\" */\n path?: string;\n}\n\nexport class SocketTransport extends EventEmitter implements Transport {\n private socket: any = null;\n private pendingHandlers: Array<{\n event: string;\n handler: (...args: any[]) => void;\n }> = [];\n private apiKey: string | null | (() => Promise<string | null>);\n private key: string | null = null;\n private url: string;\n private version: string;\n private socketPath: string;\n private waitForAuth: Promise<void> | null = null;\n private resolveAuth: (() => void) | null = null;\n private inflight = new Map<string, Promise<any>>();\n\n public loading: Promise<void>;\n public isLoading = true;\n public isConnected = false;\n public isConnecting = false;\n public authVersion = 0;\n\n constructor(config: SocketTransportConfig) {\n super();\n this.url = config.url;\n this.apiKey = config.key ?? null;\n this.version = config.version ?? \"v1\";\n this.socketPath = config.path ?? \"/ws\";\n this.loading = this.init(this.apiKey);\n }\n\n // ── Auth ──────────────────────────────────────────────────────────────\n\n async setKey(\n key: string | null | (() => Promise<string | null>),\n ): Promise<void> {\n this.apiKey = key;\n this.isLoading = true;\n this.loading = this.init(key);\n await this.loading;\n }\n\n // ── Init ──────────────────────────────────────────────────────────────\n\n private async init(\n key: string | null | (() => Promise<string | null>),\n ): Promise<void> {\n this.isLoading = true;\n this.isConnecting = true;\n\n try {\n this.key = typeof key === \"function\" ? await key() : key;\n const socketKey = `${this.url}:${this.version}`;\n\n if (!SOCKET_CONNECTIONS.has(socketKey)) {\n SOCKET_CONNECTIONS.set(\n socketKey,\n SocketIO(this.url, {\n path: this.socketPath,\n agent: true,\n transports: [\"websocket\"],\n withCredentials: true,\n query: { key: this.key ?? undefined, compression: true },\n }),\n );\n }\n\n this.socket = SOCKET_CONNECTIONS.get(socketKey);\n\n if (this.key) {\n const prevResolve = this.resolveAuth;\n this.waitForAuth = new Promise<void>((resolve) => {\n this.resolveAuth = resolve;\n this.socket.emit(\"authenticate\", this.key, () => {\n this.waitForAuth = null;\n this.resolveAuth = null;\n this.authVersion++;\n this.emit(\"authenticated\");\n if (prevResolve) prevResolve();\n resolve();\n });\n });\n } else {\n this.waitForAuth = null;\n this.resolveAuth = null;\n }\n\n this.isLoading = false;\n } catch (error) {\n this.isLoading = false;\n this.isConnecting = false;\n this.emit(\"error\", error);\n throw error;\n }\n\n this.setupEvents();\n }\n\n private setupEvents(): void {\n if (!this.socket) return;\n\n for (const { event, handler } of this.pendingHandlers) {\n this.socket.on(event, handler);\n }\n this.pendingHandlers = [];\n\n let hasConnected = this.isConnected;\n this.socket.off(\"connect\");\n this.socket.off(\"disconnect\");\n this.socket.off(\"error\");\n\n this.socket.on(\"connect\", () => {\n const wasDisconnected = !this.isConnected && hasConnected;\n this.isConnected = true;\n this.isConnecting = false;\n hasConnected = true;\n\n // Re-authenticate on reconnect\n if (wasDisconnected && this.key) {\n this.socket.emit(\"authenticate\", this.key, () => {\n this.emit(\"reconnected\");\n });\n } else {\n this.emit(wasDisconnected ? \"reconnected\" : \"connected\");\n }\n });\n\n this.socket.on(\"disconnect\", () => {\n this.isConnected = false;\n this.emit(\"disconnected\");\n });\n\n this.socket.on(\"error\", (error: Error) => {\n this.emit(\"error\", error);\n });\n }\n\n // ── Request/Response ──────────────────────────────────────────────────\n\n private async fetch(\n method: string,\n path: string,\n data: any = {},\n ): Promise<any> {\n await this.loading;\n if (this.waitForAuth) await this.waitForAuth;\n if (!this.socket) throw new Error(\"Socket not initialized\");\n\n const upper = method.toUpperCase();\n if (upper === \"GET\") {\n const dedupeKey = `GET:${path}:${this.authVersion}:${JSON.stringify(data)}`;\n const existing = this.inflight.get(dedupeKey);\n if (existing) return existing;\n const req = this._doFetch(method, path, data);\n this.inflight.set(dedupeKey, req);\n req.finally(() => this.inflight.delete(dedupeKey));\n return req;\n }\n\n return this._doFetch(method, path, data);\n }\n\n private async _doFetch(\n method: string,\n path: string,\n data: any = {},\n ): Promise<any> {\n if (!this.isConnected) {\n await new Promise<void>((resolve, reject) => {\n if (this.socket.connected) return resolve();\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error(\"Connection timeout\"));\n }, 30000);\n const onConnect = () => {\n cleanup();\n resolve();\n };\n const onError = (err: Error) => {\n cleanup();\n reject(new Error(`Connection failed: ${err.message}`));\n };\n const cleanup = () => {\n clearTimeout(timeout);\n this.socket.off(\"connect\", onConnect);\n this.socket.off(\"connect_error\", onError);\n };\n this.socket.once(\"connect\", onConnect);\n this.socket.once(\"connect_error\", onError);\n });\n }\n\n const id = uid.rnd();\n\n return new Promise((resolve, reject) => {\n this.socket.once(id, (msg: any) => {\n try {\n const uncompressed = pako.ungzip(msg, { to: \"string\" });\n const { success, result, message, error } = decompress(\n JSON.parse(uncompressed),\n );\n if (success) resolve(result);\n else\n reject(\n new Error(\n message || error || `Request failed: ${method}:${path}`,\n ),\n );\n } catch (err) {\n reject(err);\n }\n });\n this.socket.emit(\n \"call\",\n id,\n method.toUpperCase(),\n `/${this.version}${path}`,\n data,\n );\n });\n }\n\n async get(path: string, data?: any): Promise<any> {\n return this.fetch(\"get\", path, data);\n }\n async post(path: string, data?: any): Promise<any> {\n return this.fetch(\"post\", path, data);\n }\n async put(path: string, data?: any): Promise<any> {\n return this.fetch(\"put\", path, data);\n }\n async patch(path: string, data?: any): Promise<any> {\n return this.fetch(\"patch\", path, data);\n }\n async delete(path: string, data?: any): Promise<any> {\n return this.fetch(\"delete\", path, data);\n }\n\n // ── Subscriptions ─────────────────────────────────────────────────────\n\n subscribe(event: string, handler: (...args: any[]) => void): () => void {\n if (this.socket) {\n this.socket.on(event, handler);\n } else {\n this.pendingHandlers.push({ event, handler });\n }\n return () => this.unsubscribe(event, handler);\n }\n\n unsubscribe(event: string, handler?: (...args: any[]) => void): void {\n if (this.socket) this.socket.off(event, handler);\n this.pendingHandlers = this.pendingHandlers.filter(\n (h) => !(h.event === event && (!handler || h.handler === handler)),\n );\n }\n\n // ── Control messages ──────────────────────────────────────────────────\n\n async send(event: string, ...args: any[]): Promise<void> {\n if (!this.isConnected && this.socket) {\n await new Promise<void>((resolve) => {\n if (this.socket.connected) return resolve();\n this.socket.once(\"connect\", () => resolve());\n });\n }\n if (this.waitForAuth) await this.waitForAuth;\n if (this.socket) this.socket.emit(event, ...args);\n }\n\n // ── Lifecycle ─────────────────────────────────────────────────────────\n\n disconnect(): void {\n if (this.socket) {\n this.socket.disconnect();\n SOCKET_CONNECTIONS.delete(`${this.url}:${this.version}`);\n this.socket = null;\n this.isConnected = false;\n }\n }\n\n async reconnect(): Promise<void> {\n this.loading = this.init(this.apiKey);\n await this.loading;\n }\n}\n\nexport default SocketTransport;\n","/**\n * SSETransport — HTTP + Server-Sent Events implementation of the Transport interface.\n *\n * Request/response via standard fetch(). Subscriptions via EventSource.\n * Simpler than Socket.IO — no websocket infra needed. Good for read-heavy\n * apps, serverless backends, or environments where WebSocket isn't available.\n *\n * Trade-offs vs SocketTransport:\n * - Simpler infra (no sticky sessions, works behind any CDN/proxy)\n * - Server → client streaming only (no client → server streaming)\n * - Request/response is standard HTTP (cacheable, observable, debuggable)\n * - No compression (relies on HTTP gzip)\n * - No request deduplication (relies on HTTP/2 multiplexing)\n */\n\nimport { EventEmitter } from \"eventemitter3\";\nimport type { Transport } from \"@parcae/model\";\n\nexport interface SSETransportConfig {\n /** Base URL of the Parcae backend. */\n url: string;\n /** API key or async function returning a key. */\n key?: string | null | (() => Promise<string | null>);\n /** API version prefix. Default: \"v1\" */\n version?: string;\n}\n\nexport class SSETransport extends EventEmitter implements Transport {\n private url: string;\n private version: string;\n private apiKey: string | null | (() => Promise<string | null>);\n private key: string | null = null;\n private eventSources = new Map<string, EventSource>();\n\n public isConnected = true; // HTTP is \"always connected\"\n public isLoading = true;\n public loading: Promise<void>;\n\n constructor(config: SSETransportConfig) {\n super();\n this.url = config.url.replace(/\\/$/, \"\");\n this.version = config.version ?? \"v1\";\n this.apiKey = config.key ?? null;\n this.loading = this.resolveKey();\n }\n\n private async resolveKey(): Promise<void> {\n try {\n this.key =\n typeof this.apiKey === \"function\" ? await this.apiKey() : this.apiKey;\n this.isLoading = false;\n this.emit(\"connected\");\n } catch (err) {\n this.isLoading = false;\n this.emit(\"error\", err);\n }\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (this.key) h[\"Authorization\"] = `Bearer ${this.key}`;\n return h;\n }\n\n private fullUrl(path: string): string {\n return `${this.url}/${this.version}${path}`;\n }\n\n // ── Request/Response ──────────────────────────────────────────────────\n\n private async request(\n method: string,\n path: string,\n data?: any,\n ): Promise<any> {\n await this.loading;\n\n const isGet = method.toUpperCase() === \"GET\";\n let url = this.fullUrl(path);\n\n if (isGet && data) {\n const params = new URLSearchParams();\n for (const [k, v] of Object.entries(data)) {\n params.set(k, typeof v === \"object\" ? JSON.stringify(v) : String(v));\n }\n url += `?${params.toString()}`;\n }\n\n const res = await fetch(url, {\n method: method.toUpperCase(),\n headers: this.headers(),\n body: isGet ? undefined : JSON.stringify(data),\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: res.statusText }));\n throw new Error(body.error || body.message || `HTTP ${res.status}`);\n }\n\n const body = await res.json();\n if (body.success === false) throw new Error(body.error || \"Request failed\");\n return body.result ?? body;\n }\n\n async get(path: string, data?: any): Promise<any> {\n return this.request(\"GET\", path, data);\n }\n async post(path: string, data?: any): Promise<any> {\n return this.request(\"POST\", path, data);\n }\n async put(path: string, data?: any): Promise<any> {\n return this.request(\"PUT\", path, data);\n }\n async patch(path: string, data?: any): Promise<any> {\n return this.request(\"PATCH\", path, data);\n }\n async delete(path: string, data?: any): Promise<any> {\n return this.request(\"DELETE\", path, data);\n }\n\n // ── Subscriptions (via Server-Sent Events) ────────────────────────────\n\n subscribe(event: string, handler: (...args: any[]) => void): () => void {\n const url = `${this.url}/${this.version}/__events/${encodeURIComponent(event)}`;\n const source = new EventSource(url, { withCredentials: true });\n\n source.onmessage = (e) => {\n try {\n const data = JSON.parse(e.data);\n handler(data);\n } catch {\n handler(e.data);\n }\n };\n\n source.onerror = () => {\n // EventSource auto-reconnects\n };\n\n this.eventSources.set(event, source);\n\n return () => {\n source.close();\n this.eventSources.delete(event);\n };\n }\n\n unsubscribe(event: string): void {\n const source = this.eventSources.get(event);\n if (source) {\n source.close();\n this.eventSources.delete(event);\n }\n }\n\n // ── Control messages ──────────────────────────────────────────────────\n\n async send(event: string, ...args: any[]): Promise<void> {\n await this.request(\"POST\", \"/__control\", { event, args });\n }\n\n // ── Lifecycle ─────────────────────────────────────────────────────────\n\n disconnect(): void {\n for (const [, source] of this.eventSources) source.close();\n this.eventSources.clear();\n this.isConnected = false;\n this.emit(\"disconnected\");\n }\n\n async reconnect(): Promise<void> {\n this.loading = this.resolveKey();\n await this.loading;\n }\n}\n\nexport default SSETransport;\n","/**\n * @parcae/sdk — createClient()\n *\n * Creates a Parcae client with a pluggable transport layer.\n * Default: Socket.IO (bidirectional, realtime).\n * Alternative: SSE (HTTP + Server-Sent Events, simpler).\n *\n * The transport is abstracted — the client exposes the same API\n * regardless of which transport is used underneath.\n */\n\nimport { Model, FrontendAdapter } from \"@parcae/model\";\nimport type { Transport } from \"@parcae/model\";\nimport { SocketTransport } from \"./transports/socket\";\nimport type { SocketTransportConfig } from \"./transports/socket\";\nimport { SSETransport } from \"./transports/sse\";\nimport type { SSETransportConfig } from \"./transports/sse\";\n\n// ─── Configuration ───────────────────────────────────────────────────────────\n\nexport interface ClientConfig {\n /** URL of the Parcae backend. */\n url: string;\n /** API key — string or async function that returns a key. */\n key?: string | null | (() => Promise<string | null>);\n /** API version prefix. Default: \"v1\" */\n version?: string;\n /**\n * Transport type. Default: \"socket\"\n * - \"socket\": Socket.IO (bidirectional, realtime subscriptions)\n * - \"sse\": HTTP + Server-Sent Events (read-heavy, simpler infra)\n * - Transport instance: provide your own Transport implementation\n */\n transport?: \"socket\" | \"sse\" | Transport;\n}\n\nexport interface ParcaeClient {\n /** The underlying transport instance. */\n transport: Transport;\n /** Shorthand for transport methods. */\n get(path: string, data?: any): Promise<any>;\n post(path: string, data?: any): Promise<any>;\n put(path: string, data?: any): Promise<any>;\n patch(path: string, data?: any): Promise<any>;\n delete(path: string, data?: any): Promise<any>;\n /** Subscribe to a named event. Returns dispose function. */\n subscribe(event: string, handler: (...args: any[]) => void): () => void;\n /** Unsubscribe from a named event. */\n unsubscribe(event: string, handler?: (...args: any[]) => void): void;\n /** Send a control message. */\n send(event: string, ...args: any[]): void;\n /** Connection state. */\n readonly isConnected: boolean;\n readonly isLoading: boolean;\n /** Promise that resolves when the client is ready. */\n loading: Promise<void>;\n /** Update the auth key. */\n setKey(key: string | null | (() => Promise<string | null>)): Promise<void>;\n /** Listen for transport events. */\n on(event: string, handler: (...args: any[]) => void): void;\n off(event: string, handler?: (...args: any[]) => void): void;\n /** Disconnect from the server. */\n disconnect(): void;\n /** Reconnect. */\n reconnect(): Promise<void>;\n /** Auth version — incremented on auth changes. Useful for cache invalidation. */\n readonly authVersion: number;\n}\n\n// ─── createClient ────────────────────────────────────────────────────────────\n\nexport function createClient(config: ClientConfig): ParcaeClient {\n const version = config.version ?? \"v1\";\n\n // Create the transport\n let transport: Transport & {\n loading?: Promise<void>;\n isLoading?: boolean;\n isConnected?: boolean;\n authVersion?: number;\n setKey?: (key: any) => Promise<void>;\n on?: (event: string, handler: (...args: any[]) => void) => void;\n off?: (event: string, handler?: (...args: any[]) => void) => void;\n disconnect?: () => void;\n reconnect?: () => Promise<void>;\n };\n\n if (config.transport && typeof config.transport === \"object\") {\n // Custom transport instance\n transport = config.transport as any;\n } else if (config.transport === \"sse\") {\n transport = new SSETransport({\n url: config.url,\n key: config.key,\n version,\n });\n } else {\n // Default: Socket.IO\n transport = new SocketTransport({\n url: config.url,\n key: config.key,\n version,\n });\n }\n\n // Wire up FrontendAdapter so Model.where(), .findById() etc work\n Model.use(new FrontendAdapter(transport));\n\n const client: ParcaeClient = {\n transport,\n\n get: (path, data) => transport.get(path, data),\n post: (path, data) => transport.post(path, data),\n put: (path, data) => transport.put(path, data),\n patch: (path, data) => transport.patch(path, data),\n delete: (path, data) => transport.delete(path, data),\n\n subscribe(event, handler) {\n if (transport.subscribe) return transport.subscribe(event, handler);\n return () => {}; // no-op if transport doesn't support subscriptions\n },\n\n unsubscribe(event, handler) {\n transport.unsubscribe?.(event, handler);\n },\n\n send(event, ...args) {\n (transport as any).send?.(event, ...args);\n },\n\n get isConnected() {\n return transport.isConnected ?? false;\n },\n get isLoading() {\n return transport.isLoading ?? false;\n },\n get loading() {\n return (transport as any).loading ?? Promise.resolve();\n },\n get authVersion() {\n return (transport as any).authVersion ?? 0;\n },\n\n async setKey(key) {\n if ((transport as any).setKey) await (transport as any).setKey(key);\n },\n\n on(event, handler) {\n transport.on?.(event, handler);\n },\n off(event, handler) {\n transport.off?.(event, handler);\n },\n\n disconnect() {\n transport.disconnect?.();\n },\n async reconnect() {\n await transport.reconnect?.();\n },\n };\n\n return client;\n}\n"]}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { Transport } from '@parcae/model';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @parcae/sdk — createClient()
|
|
5
|
-
*
|
|
6
|
-
* Creates a Parcae client with a pluggable transport layer.
|
|
7
|
-
* Default: Socket.IO (bidirectional, realtime).
|
|
8
|
-
* Alternative: SSE (HTTP + Server-Sent Events, simpler).
|
|
9
|
-
*
|
|
10
|
-
* The transport is abstracted — the client exposes the same API
|
|
11
|
-
* regardless of which transport is used underneath.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
interface ClientConfig {
|
|
15
|
-
/** URL of the Parcae backend. */
|
|
16
|
-
url: string;
|
|
17
|
-
/** API key — string or async function that returns a key. */
|
|
18
|
-
key?: string | null | (() => Promise<string | null>);
|
|
19
|
-
/** API version prefix. Default: "v1" */
|
|
20
|
-
version?: string;
|
|
21
|
-
/**
|
|
22
|
-
* Transport type. Default: "socket"
|
|
23
|
-
* - "socket": Socket.IO (bidirectional, realtime subscriptions)
|
|
24
|
-
* - "sse": HTTP + Server-Sent Events (read-heavy, simpler infra)
|
|
25
|
-
* - Transport instance: provide your own Transport implementation
|
|
26
|
-
*/
|
|
27
|
-
transport?: "socket" | "sse" | Transport;
|
|
28
|
-
}
|
|
29
|
-
interface ParcaeClient {
|
|
30
|
-
/** The underlying transport instance. */
|
|
31
|
-
transport: Transport;
|
|
32
|
-
/** Shorthand for transport methods. */
|
|
33
|
-
get(path: string, data?: any): Promise<any>;
|
|
34
|
-
post(path: string, data?: any): Promise<any>;
|
|
35
|
-
put(path: string, data?: any): Promise<any>;
|
|
36
|
-
patch(path: string, data?: any): Promise<any>;
|
|
37
|
-
delete(path: string, data?: any): Promise<any>;
|
|
38
|
-
/** Subscribe to a named event. Returns dispose function. */
|
|
39
|
-
subscribe(event: string, handler: (...args: any[]) => void): () => void;
|
|
40
|
-
/** Unsubscribe from a named event. */
|
|
41
|
-
unsubscribe(event: string, handler?: (...args: any[]) => void): void;
|
|
42
|
-
/** Send a control message. */
|
|
43
|
-
send(event: string, ...args: any[]): void;
|
|
44
|
-
/** Connection state. */
|
|
45
|
-
readonly isConnected: boolean;
|
|
46
|
-
readonly isLoading: boolean;
|
|
47
|
-
/** Promise that resolves when the client is ready. */
|
|
48
|
-
loading: Promise<void>;
|
|
49
|
-
/** Update the auth key. */
|
|
50
|
-
setKey(key: string | null | (() => Promise<string | null>)): Promise<void>;
|
|
51
|
-
/** Listen for transport events. */
|
|
52
|
-
on(event: string, handler: (...args: any[]) => void): void;
|
|
53
|
-
off(event: string, handler?: (...args: any[]) => void): void;
|
|
54
|
-
/** Disconnect from the server. */
|
|
55
|
-
disconnect(): void;
|
|
56
|
-
/** Reconnect. */
|
|
57
|
-
reconnect(): Promise<void>;
|
|
58
|
-
/** Auth version — incremented on auth changes. Useful for cache invalidation. */
|
|
59
|
-
readonly authVersion: number;
|
|
60
|
-
}
|
|
61
|
-
declare function createClient(config: ClientConfig): ParcaeClient;
|
|
62
|
-
|
|
63
|
-
export { type ClientConfig as C, type ParcaeClient as P, createClient as c };
|