@powerdata/pd4 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +356 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +185 -0
- package/dist/index.d.ts +185 -0
- package/dist/index.js +324 -0
- package/dist/index.js.map +1 -0
- package/dist/react/index.cjs +523 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +198 -0
- package/dist/react/index.d.ts +198 -0
- package/dist/react/index.js +492 -0
- package/dist/react/index.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
// src/react/context.tsx
|
|
2
|
+
import { createContext, useContext, useRef } from "react";
|
|
3
|
+
|
|
4
|
+
// src/errors.ts
|
|
5
|
+
var PD4Error = class extends Error {
|
|
6
|
+
constructor(message, status, url) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = "PD4Error";
|
|
9
|
+
this.status = status;
|
|
10
|
+
this.url = url;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// src/utils.ts
|
|
15
|
+
function flattenRow(row) {
|
|
16
|
+
const flat = { _pk: row.key };
|
|
17
|
+
for (const cv of row.values) {
|
|
18
|
+
flat[cv.column] = cv.value;
|
|
19
|
+
}
|
|
20
|
+
return flat;
|
|
21
|
+
}
|
|
22
|
+
function toColumnar(flatRows, columnNames) {
|
|
23
|
+
if (flatRows.length === 0) return { columns: [], rows: [] };
|
|
24
|
+
const cols = columnNames ?? Object.keys(flatRows[0]).filter((k) => k !== "_pk");
|
|
25
|
+
const rows = flatRows.map((row) => cols.map((c) => row[c] ?? null));
|
|
26
|
+
return { columns: cols, rows };
|
|
27
|
+
}
|
|
28
|
+
function toColumnValues(flat) {
|
|
29
|
+
return Object.entries(flat).filter(([k]) => k !== "_pk").map(([column, value]) => ({ column, value }));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// src/buffer.ts
|
|
33
|
+
var PD4Buffer = class {
|
|
34
|
+
constructor(client, handle, table) {
|
|
35
|
+
this.client = client;
|
|
36
|
+
this.handle = handle;
|
|
37
|
+
this.table = table;
|
|
38
|
+
}
|
|
39
|
+
/** Update a row within the buffer (not visible to others until commit). */
|
|
40
|
+
async update(key, values) {
|
|
41
|
+
const pairs = toColumnValues(values);
|
|
42
|
+
await this._request(`views/${this.handle}/rows/update`, {
|
|
43
|
+
method: "POST",
|
|
44
|
+
body: JSON.stringify({ key, values: pairs })
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/** Fetch rows from the buffer (sees uncommitted changes). */
|
|
48
|
+
async fetch(offset = 0, limit = 100) {
|
|
49
|
+
const data = await this._request(
|
|
50
|
+
`views/${this.handle}/rows?offset=${offset}&limit=${limit}`
|
|
51
|
+
);
|
|
52
|
+
return {
|
|
53
|
+
rows: data.rows.map(flattenRow),
|
|
54
|
+
total: data.total
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/** Commit all buffered writes atomically. Fires SSE events. */
|
|
58
|
+
async commit() {
|
|
59
|
+
await this._request(`views/${this.handle}/commit`, { method: "POST" });
|
|
60
|
+
}
|
|
61
|
+
/** Rollback all buffered writes (discard pending changes). */
|
|
62
|
+
async rollback() {
|
|
63
|
+
await this._request(`views/${this.handle}/rollback`, { method: "POST" });
|
|
64
|
+
}
|
|
65
|
+
// --- Internal ----------------------------------------------------------
|
|
66
|
+
async _request(path, init) {
|
|
67
|
+
const url = `${this.client.url}/v1/${this.client.db}/${path}`;
|
|
68
|
+
const res = await fetch(url, {
|
|
69
|
+
...init,
|
|
70
|
+
headers: { "Content-Type": "application/json", ...init?.headers }
|
|
71
|
+
});
|
|
72
|
+
if (!res.ok) {
|
|
73
|
+
const text = await res.text();
|
|
74
|
+
throw new Error(`PD4 Buffer ${init?.method ?? "GET"} ${url}: ${res.status} ${text}`);
|
|
75
|
+
}
|
|
76
|
+
if (res.status === 204) return void 0;
|
|
77
|
+
return res.json();
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// src/client.ts
|
|
82
|
+
var PD4Client = class {
|
|
83
|
+
constructor(url, db, options) {
|
|
84
|
+
this.eventSource = null;
|
|
85
|
+
this.handlers = /* @__PURE__ */ new Map();
|
|
86
|
+
this.statusHandlers = [];
|
|
87
|
+
this._status = "connecting";
|
|
88
|
+
this.url = url.replace(/\/$/, "");
|
|
89
|
+
this.db = db;
|
|
90
|
+
this.EventSourceCtor = options?.EventSource ?? (typeof globalThis !== "undefined" && globalThis.EventSource ? globalThis.EventSource : null);
|
|
91
|
+
}
|
|
92
|
+
// --- URL helpers -------------------------------------------------------
|
|
93
|
+
get v1() {
|
|
94
|
+
return `${this.url}/v1/${this.db}`;
|
|
95
|
+
}
|
|
96
|
+
get api() {
|
|
97
|
+
return `${this.url}/api/${this.db}`;
|
|
98
|
+
}
|
|
99
|
+
// --- HTTP helper -------------------------------------------------------
|
|
100
|
+
async request(url, init) {
|
|
101
|
+
const res = await fetch(url, {
|
|
102
|
+
...init,
|
|
103
|
+
headers: { "Content-Type": "application/json", ...init?.headers }
|
|
104
|
+
});
|
|
105
|
+
if (!res.ok) {
|
|
106
|
+
const text = await res.text();
|
|
107
|
+
throw new PD4Error(
|
|
108
|
+
`PD4 ${init?.method ?? "GET"} ${url}: ${res.status} ${text}`,
|
|
109
|
+
res.status,
|
|
110
|
+
url
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
if (res.status === 204) return void 0;
|
|
114
|
+
return res.json();
|
|
115
|
+
}
|
|
116
|
+
// --- Health ------------------------------------------------------------
|
|
117
|
+
/** Check if PD4 is reachable */
|
|
118
|
+
async ping() {
|
|
119
|
+
try {
|
|
120
|
+
const res = await fetch(`${this.url}/health`);
|
|
121
|
+
return res.ok;
|
|
122
|
+
} catch {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// --- Database ----------------------------------------------------------
|
|
127
|
+
/** Ensure the database is open */
|
|
128
|
+
async ensureDatabase() {
|
|
129
|
+
await this.request(`${this.url}/v1/db`, {
|
|
130
|
+
method: "POST",
|
|
131
|
+
body: JSON.stringify({ name: this.db })
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// --- Tables ------------------------------------------------------------
|
|
135
|
+
/** List all table names */
|
|
136
|
+
async listTables() {
|
|
137
|
+
const data = await this.request(`${this.v1}/tables`);
|
|
138
|
+
return data.tables;
|
|
139
|
+
}
|
|
140
|
+
/** Get table info */
|
|
141
|
+
async getTable(name) {
|
|
142
|
+
return this.request(`${this.v1}/tables/${name}`);
|
|
143
|
+
}
|
|
144
|
+
/** Create a table (with auto_pk) */
|
|
145
|
+
async createTable(name) {
|
|
146
|
+
await this.request(`${this.v1}/tables`, {
|
|
147
|
+
method: "POST",
|
|
148
|
+
body: JSON.stringify({ name, auto_pk: true })
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
/** Drop a table */
|
|
152
|
+
async dropTable(name) {
|
|
153
|
+
await this.request(`${this.v1}/tables/${name}`, { method: "DELETE" });
|
|
154
|
+
}
|
|
155
|
+
/** Add a column to a table */
|
|
156
|
+
async addColumn(table, name, dtype) {
|
|
157
|
+
await this.request(`${this.v1}/tables/${table}/columns`, {
|
|
158
|
+
method: "POST",
|
|
159
|
+
body: JSON.stringify({ name, dtype })
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
// --- Rows (flat objects in, flat objects out) ---------------------------
|
|
163
|
+
/** Insert one or more rows (flat objects). Returns keys and count. */
|
|
164
|
+
async insert(table, rows) {
|
|
165
|
+
const arr = Array.isArray(rows) ? rows : [rows];
|
|
166
|
+
const { columns, rows: colRows } = toColumnar(arr);
|
|
167
|
+
return this.request(`${this.v1}/tables/${table}/rows`, {
|
|
168
|
+
method: "POST",
|
|
169
|
+
body: JSON.stringify({ columns, rows: colRows })
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/** Update a single row by key with a flat object of changed columns. */
|
|
173
|
+
async update(table, key, values) {
|
|
174
|
+
const pairs = toColumnValues(values);
|
|
175
|
+
await this.request(`${this.v1}/views/${table}/rows/update`, {
|
|
176
|
+
method: "POST",
|
|
177
|
+
body: JSON.stringify({ key, values: pairs })
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/** Delete rows by keys. */
|
|
181
|
+
async delete(table, keys) {
|
|
182
|
+
const arr = Array.isArray(keys) ? keys : [keys];
|
|
183
|
+
await this.request(`${this.v1}/views/${table}/rows/delete`, {
|
|
184
|
+
method: "POST",
|
|
185
|
+
body: JSON.stringify({ keys: arr })
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
/** Fetch rows from a table/view. Returns flat Row objects. */
|
|
189
|
+
async fetch(table, opts) {
|
|
190
|
+
const offset = opts?.offset ?? 0;
|
|
191
|
+
const limit = opts?.limit ?? 1e3;
|
|
192
|
+
const data = await this.request(
|
|
193
|
+
`${this.v1}/views/${table}/rows?offset=${offset}&limit=${limit}`
|
|
194
|
+
);
|
|
195
|
+
return {
|
|
196
|
+
rows: data.rows.map(flattenRow),
|
|
197
|
+
total: data.total
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
// --- Raw row access (PD4 wire format) ----------------------------------
|
|
201
|
+
/** Insert rows in columnar format (low-level). */
|
|
202
|
+
async insertColumnar(table, columns, rows) {
|
|
203
|
+
return this.request(`${this.v1}/tables/${table}/rows`, {
|
|
204
|
+
method: "POST",
|
|
205
|
+
body: JSON.stringify({ columns, rows })
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
/** Update a row by key with column-value pairs (low-level). */
|
|
209
|
+
async updateRaw(table, key, values) {
|
|
210
|
+
await this.request(`${this.v1}/views/${table}/rows/update`, {
|
|
211
|
+
method: "POST",
|
|
212
|
+
body: JSON.stringify({ key, values })
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
/** Fetch rows in PD4 wire format (low-level). */
|
|
216
|
+
async fetchRaw(table, offset = 0, limit = 1e3) {
|
|
217
|
+
return this.request(`${this.v1}/views/${table}/rows?offset=${offset}&limit=${limit}`);
|
|
218
|
+
}
|
|
219
|
+
// --- Buffer ------------------------------------------------------------
|
|
220
|
+
/** Create a buffered view wrapping a table. */
|
|
221
|
+
async buffer(table) {
|
|
222
|
+
const info = await this.request(
|
|
223
|
+
`${this.v1}/views/${table}/buffer`,
|
|
224
|
+
{ method: "POST" }
|
|
225
|
+
);
|
|
226
|
+
return new PD4Buffer(this, info.handle, table);
|
|
227
|
+
}
|
|
228
|
+
// --- SSE ---------------------------------------------------------------
|
|
229
|
+
/** Get current SSE connection status. */
|
|
230
|
+
get status() {
|
|
231
|
+
return this._status;
|
|
232
|
+
}
|
|
233
|
+
/** Connect to the SSE event stream. Called automatically on first on(). */
|
|
234
|
+
connect() {
|
|
235
|
+
if (this.eventSource) return;
|
|
236
|
+
if (!this.EventSourceCtor) {
|
|
237
|
+
throw new Error(
|
|
238
|
+
'EventSource is not available. In Node.js, pass { EventSource } from the "eventsource" package to the PD4Client constructor.'
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
this._setStatus("connecting");
|
|
242
|
+
const sse = new this.EventSourceCtor(`${this.api}/events`);
|
|
243
|
+
this.eventSource = sse;
|
|
244
|
+
sse.addEventListener("session", () => {
|
|
245
|
+
this._setStatus("connected");
|
|
246
|
+
});
|
|
247
|
+
sse.addEventListener("insert", (e) => {
|
|
248
|
+
const data = JSON.parse(e.data);
|
|
249
|
+
const table = data.handle;
|
|
250
|
+
const keys = data.keys ?? [];
|
|
251
|
+
const newValues = data.new_values ?? [];
|
|
252
|
+
this._dispatch(table, "insert", keys, newValues, []);
|
|
253
|
+
});
|
|
254
|
+
sse.addEventListener("update", (e) => {
|
|
255
|
+
const data = JSON.parse(e.data);
|
|
256
|
+
const table = data.handle;
|
|
257
|
+
const keys = data.keys ?? [];
|
|
258
|
+
const newValues = data.new_values ?? [];
|
|
259
|
+
const oldValues = data.old_values ?? [];
|
|
260
|
+
this._dispatch(table, "update", keys, newValues, oldValues);
|
|
261
|
+
});
|
|
262
|
+
sse.addEventListener("delete", (e) => {
|
|
263
|
+
const data = JSON.parse(e.data);
|
|
264
|
+
const table = data.handle;
|
|
265
|
+
const keys = data.keys ?? [];
|
|
266
|
+
this._dispatch(table, "delete", keys, [], []);
|
|
267
|
+
});
|
|
268
|
+
sse.onerror = () => {
|
|
269
|
+
this._setStatus("error");
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
/** Disconnect from the SSE event stream. */
|
|
273
|
+
disconnect() {
|
|
274
|
+
this.eventSource?.close();
|
|
275
|
+
this.eventSource = null;
|
|
276
|
+
this._setStatus("connecting");
|
|
277
|
+
}
|
|
278
|
+
on(table, event, handler) {
|
|
279
|
+
if (!this.eventSource) this.connect();
|
|
280
|
+
let tableHandlers = this.handlers.get(table);
|
|
281
|
+
if (!tableHandlers) {
|
|
282
|
+
tableHandlers = { insert: [], update: [], delete: [] };
|
|
283
|
+
this.handlers.set(table, tableHandlers);
|
|
284
|
+
}
|
|
285
|
+
const list = tableHandlers[event];
|
|
286
|
+
list.push(handler);
|
|
287
|
+
return () => {
|
|
288
|
+
const idx = list.indexOf(handler);
|
|
289
|
+
if (idx >= 0) list.splice(idx, 1);
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
/** Subscribe to connection status changes. Returns an unsubscribe function. */
|
|
293
|
+
onStatus(handler) {
|
|
294
|
+
this.statusHandlers.push(handler);
|
|
295
|
+
return () => {
|
|
296
|
+
const idx = this.statusHandlers.indexOf(handler);
|
|
297
|
+
if (idx >= 0) this.statusHandlers.splice(idx, 1);
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
// --- SSE internals -----------------------------------------------------
|
|
301
|
+
_setStatus(status) {
|
|
302
|
+
this._status = status;
|
|
303
|
+
for (const handler of this.statusHandlers) {
|
|
304
|
+
handler(status);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
_dispatch(table, event, keys, newValues, oldValues) {
|
|
308
|
+
const tableHandlers = this.handlers.get(table);
|
|
309
|
+
if (!tableHandlers) return;
|
|
310
|
+
if (event === "insert") {
|
|
311
|
+
for (const h of tableHandlers.insert) h(keys, newValues);
|
|
312
|
+
} else if (event === "update") {
|
|
313
|
+
for (const h of tableHandlers.update) h(keys, newValues, oldValues);
|
|
314
|
+
} else {
|
|
315
|
+
for (const h of tableHandlers.delete) h(keys);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
// src/react/context.tsx
|
|
321
|
+
import { jsx } from "react/jsx-runtime";
|
|
322
|
+
var PD4Context = createContext(null);
|
|
323
|
+
function PD4Provider({ url, db, children }) {
|
|
324
|
+
const clientRef = useRef(null);
|
|
325
|
+
if (!clientRef.current) {
|
|
326
|
+
clientRef.current = new PD4Client(url, db);
|
|
327
|
+
}
|
|
328
|
+
return /* @__PURE__ */ jsx(PD4Context.Provider, { value: clientRef.current, children });
|
|
329
|
+
}
|
|
330
|
+
function usePD4() {
|
|
331
|
+
const client = useContext(PD4Context);
|
|
332
|
+
if (!client) {
|
|
333
|
+
throw new Error("usePD4() must be used within a <PD4Provider>");
|
|
334
|
+
}
|
|
335
|
+
return client;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// src/react/usePD4Subscribe.ts
|
|
339
|
+
import { useEffect, useRef as useRef2 } from "react";
|
|
340
|
+
function usePD4Subscribe(table, event, handler) {
|
|
341
|
+
const db = usePD4();
|
|
342
|
+
const handlerRef = useRef2(handler);
|
|
343
|
+
handlerRef.current = handler;
|
|
344
|
+
useEffect(() => {
|
|
345
|
+
const wrapper = (...args) => {
|
|
346
|
+
;
|
|
347
|
+
handlerRef.current(...args);
|
|
348
|
+
};
|
|
349
|
+
return db.on(table, event, wrapper);
|
|
350
|
+
}, [db, table, event]);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// src/react/usePD4Table.ts
|
|
354
|
+
import { useState, useEffect as useEffect2, useCallback, useRef as useRef3 } from "react";
|
|
355
|
+
var HIGHLIGHT_MS = 1500;
|
|
356
|
+
function usePD4Table(table, opts) {
|
|
357
|
+
const db = usePD4();
|
|
358
|
+
const limit = opts?.limit ?? 1e3;
|
|
359
|
+
const deleteDelay = opts?.deleteDelay ?? HIGHLIGHT_MS;
|
|
360
|
+
const [rows, setRows] = useState([]);
|
|
361
|
+
const [total, setTotal] = useState(0);
|
|
362
|
+
const [columns, setColumns] = useState([]);
|
|
363
|
+
const [status, setStatus] = useState("connecting");
|
|
364
|
+
const [highlights, setHighlights] = useState({});
|
|
365
|
+
const tableRef = useRef3(table);
|
|
366
|
+
tableRef.current = table;
|
|
367
|
+
const highlightKeys = useCallback((keys, type) => {
|
|
368
|
+
if (keys.length === 0) return;
|
|
369
|
+
setHighlights((prev) => {
|
|
370
|
+
const next = { ...prev };
|
|
371
|
+
for (const k of keys) next[k] = type;
|
|
372
|
+
return next;
|
|
373
|
+
});
|
|
374
|
+
setTimeout(() => {
|
|
375
|
+
setHighlights((prev) => {
|
|
376
|
+
const next = { ...prev };
|
|
377
|
+
for (const k of keys) {
|
|
378
|
+
if (next[k] === type) delete next[k];
|
|
379
|
+
}
|
|
380
|
+
return next;
|
|
381
|
+
});
|
|
382
|
+
}, HIGHLIGHT_MS);
|
|
383
|
+
}, []);
|
|
384
|
+
const fetchRows = useCallback(async () => {
|
|
385
|
+
try {
|
|
386
|
+
const { rows: fetched, total: t } = await db.fetch(tableRef.current, { offset: 0, limit });
|
|
387
|
+
setRows(fetched);
|
|
388
|
+
setTotal(t);
|
|
389
|
+
} catch {
|
|
390
|
+
}
|
|
391
|
+
}, [db, limit]);
|
|
392
|
+
useEffect2(() => {
|
|
393
|
+
let cancelled = false;
|
|
394
|
+
const unsubs = [];
|
|
395
|
+
(async () => {
|
|
396
|
+
try {
|
|
397
|
+
const info = await db.getTable(table);
|
|
398
|
+
if (cancelled) return;
|
|
399
|
+
setColumns(info.columns.filter((c) => c.name !== "_pk"));
|
|
400
|
+
await fetchRows();
|
|
401
|
+
if (cancelled) return;
|
|
402
|
+
setStatus("connected");
|
|
403
|
+
unsubs.push(db.on(table, "insert", (keys, newValues) => {
|
|
404
|
+
if (cancelled) return;
|
|
405
|
+
const newRows = keys.map((k, i) => ({ _pk: k, ...newValues[i] }));
|
|
406
|
+
setRows((prev) => [...prev, ...newRows]);
|
|
407
|
+
setTotal((prev) => prev + newRows.length);
|
|
408
|
+
highlightKeys(keys, "insert");
|
|
409
|
+
}));
|
|
410
|
+
unsubs.push(db.on(table, "update", (keys, newValues) => {
|
|
411
|
+
if (cancelled) return;
|
|
412
|
+
if (newValues.length === 0 || typeof newValues[0] !== "object" || newValues[0] === null) {
|
|
413
|
+
fetchRows();
|
|
414
|
+
highlightKeys(keys, "update");
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
const updateMap = new Map(keys.map((k, i) => [k, newValues[i]]));
|
|
418
|
+
setRows(
|
|
419
|
+
(prev) => prev.map((row) => {
|
|
420
|
+
const changes = updateMap.get(row._pk);
|
|
421
|
+
if (!changes) return row;
|
|
422
|
+
return { ...row, ...changes };
|
|
423
|
+
})
|
|
424
|
+
);
|
|
425
|
+
highlightKeys(keys, "update");
|
|
426
|
+
}));
|
|
427
|
+
unsubs.push(db.on(table, "delete", (keys) => {
|
|
428
|
+
if (cancelled) return;
|
|
429
|
+
const keySet = new Set(keys);
|
|
430
|
+
highlightKeys(keys, "delete");
|
|
431
|
+
setTimeout(() => {
|
|
432
|
+
setRows((prev) => prev.filter((row) => !keySet.has(row._pk)));
|
|
433
|
+
setTotal((prev) => Math.max(0, prev - keys.length));
|
|
434
|
+
}, deleteDelay);
|
|
435
|
+
}));
|
|
436
|
+
} catch {
|
|
437
|
+
if (!cancelled) {
|
|
438
|
+
setStatus("error");
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
})();
|
|
442
|
+
return () => {
|
|
443
|
+
cancelled = true;
|
|
444
|
+
for (const unsub of unsubs) unsub();
|
|
445
|
+
};
|
|
446
|
+
}, [db, table, limit, fetchRows, highlightKeys, deleteDelay]);
|
|
447
|
+
return { rows, total, columns, status, highlights };
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// src/react/usePD4Query.ts
|
|
451
|
+
import { useState as useState2, useEffect as useEffect3 } from "react";
|
|
452
|
+
function usePD4Query(table, offset = 0, limit = 1e3) {
|
|
453
|
+
const db = usePD4();
|
|
454
|
+
const [rows, setRows] = useState2([]);
|
|
455
|
+
const [total, setTotal] = useState2(0);
|
|
456
|
+
const [loading, setLoading] = useState2(true);
|
|
457
|
+
const [error, setError] = useState2(null);
|
|
458
|
+
const [attempt, setAttempt] = useState2(0);
|
|
459
|
+
useEffect3(() => {
|
|
460
|
+
let cancelled = false;
|
|
461
|
+
setLoading(true);
|
|
462
|
+
setError(null);
|
|
463
|
+
db.fetch(table, { offset, limit }).then((result) => {
|
|
464
|
+
if (cancelled) return;
|
|
465
|
+
setRows(result.rows);
|
|
466
|
+
setTotal(result.total);
|
|
467
|
+
setLoading(false);
|
|
468
|
+
}).catch((err) => {
|
|
469
|
+
if (cancelled) return;
|
|
470
|
+
setError(err instanceof Error ? err.message : "Query failed");
|
|
471
|
+
setLoading(false);
|
|
472
|
+
});
|
|
473
|
+
return () => {
|
|
474
|
+
cancelled = true;
|
|
475
|
+
};
|
|
476
|
+
}, [db, table, offset, limit, attempt]);
|
|
477
|
+
return {
|
|
478
|
+
rows,
|
|
479
|
+
total,
|
|
480
|
+
loading,
|
|
481
|
+
error,
|
|
482
|
+
refetch: () => setAttempt((a) => a + 1)
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
export {
|
|
486
|
+
PD4Provider,
|
|
487
|
+
usePD4,
|
|
488
|
+
usePD4Query,
|
|
489
|
+
usePD4Subscribe,
|
|
490
|
+
usePD4Table
|
|
491
|
+
};
|
|
492
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/react/context.tsx","../../src/errors.ts","../../src/utils.ts","../../src/buffer.ts","../../src/client.ts","../../src/react/usePD4Subscribe.ts","../../src/react/usePD4Table.ts","../../src/react/usePD4Query.ts"],"sourcesContent":["import { createContext, useContext, useRef } from 'react'\nimport { PD4Client } from '../client'\n\nconst PD4Context = createContext<PD4Client | null>(null)\n\nexport interface PD4ProviderProps {\n url: string\n db: string\n children: React.ReactNode\n}\n\nexport function PD4Provider({ url, db, children }: PD4ProviderProps) {\n const clientRef = useRef<PD4Client | null>(null)\n if (!clientRef.current) {\n clientRef.current = new PD4Client(url, db)\n }\n return <PD4Context.Provider value={clientRef.current}>{children}</PD4Context.Provider>\n}\n\nexport function usePD4(): PD4Client {\n const client = useContext(PD4Context)\n if (!client) {\n throw new Error('usePD4() must be used within a <PD4Provider>')\n }\n return client\n}\n","/** Base error class for PD4 client errors */\nexport class PD4Error extends Error {\n readonly status: number | undefined\n readonly url: string | undefined\n\n constructor(message: string, status?: number, url?: string) {\n super(message)\n this.name = 'PD4Error'\n this.status = status\n this.url = url\n }\n}\n","import type { PD4Row, Row } from './types'\n\n/** Convert PD4 row format to flat record */\nexport function flattenRow(row: PD4Row): Row {\n const flat: Row = { _pk: row.key }\n for (const cv of row.values) {\n flat[cv.column] = cv.value\n }\n return flat\n}\n\n/**\n * Convert flat row objects to PD4's columnar insert format.\n * Returns { columns, rows } suitable for the insert endpoint.\n */\nexport function toColumnar(\n flatRows: Row[],\n columnNames?: string[],\n): { columns: string[]; rows: (string | number | boolean | null)[][] } {\n if (flatRows.length === 0) return { columns: [], rows: [] }\n const cols = columnNames ?? Object.keys(flatRows[0]).filter((k) => k !== '_pk')\n const rows = flatRows.map((row) => cols.map((c) => row[c] ?? null))\n return { columns: cols, rows }\n}\n\n/**\n * Convert a flat row object to PD4's column-value pairs for update.\n * Filters out the _pk field.\n */\nexport function toColumnValues(\n flat: Row,\n): { column: string; value: string | number | boolean | null }[] {\n return Object.entries(flat)\n .filter(([k]) => k !== '_pk')\n .map(([column, value]) => ({ column, value }))\n}\n","import type { PD4Client } from './client'\nimport { flattenRow, toColumnValues } from './utils'\nimport type { Row, FetchResult, PD4Row } from './types'\n\n/**\n * A buffered view wrapping a PD4 table.\n * Changes are accumulated locally and only become visible\n * to other clients after commit().\n */\nexport class PD4Buffer {\n private client: PD4Client\n readonly handle: string\n readonly table: string\n\n constructor(client: PD4Client, handle: string, table: string) {\n this.client = client\n this.handle = handle\n this.table = table\n }\n\n /** Update a row within the buffer (not visible to others until commit). */\n async update(key: number, values: Row): Promise<void> {\n const pairs = toColumnValues(values)\n await this._request(`views/${this.handle}/rows/update`, {\n method: 'POST',\n body: JSON.stringify({ key, values: pairs }),\n })\n }\n\n /** Fetch rows from the buffer (sees uncommitted changes). */\n async fetch(offset = 0, limit = 100): Promise<FetchResult> {\n const data = await this._request<{ rows: PD4Row[]; total: number }>(\n `views/${this.handle}/rows?offset=${offset}&limit=${limit}`,\n )\n return {\n rows: data.rows.map(flattenRow),\n total: data.total,\n }\n }\n\n /** Commit all buffered writes atomically. Fires SSE events. */\n async commit(): Promise<void> {\n await this._request(`views/${this.handle}/commit`, { method: 'POST' })\n }\n\n /** Rollback all buffered writes (discard pending changes). */\n async rollback(): Promise<void> {\n await this._request(`views/${this.handle}/rollback`, { method: 'POST' })\n }\n\n // --- Internal ----------------------------------------------------------\n\n private async _request<T>(path: string, init?: RequestInit): Promise<T> {\n const url = `${this.client.url}/v1/${this.client.db}/${path}`\n const res = await fetch(url, {\n ...init,\n headers: { 'Content-Type': 'application/json', ...init?.headers },\n })\n if (!res.ok) {\n const text = await res.text()\n throw new Error(`PD4 Buffer ${init?.method ?? 'GET'} ${url}: ${res.status} ${text}`)\n }\n if (res.status === 204) return undefined as T\n return res.json()\n }\n}\n","import { PD4Error } from './errors'\nimport { flattenRow, toColumnar, toColumnValues } from './utils'\nimport { PD4Buffer } from './buffer'\nimport type {\n ColumnInfo,\n TableInfo,\n PD4Row,\n Row,\n FetchOptions,\n FetchResult,\n InsertResult,\n ConnectionStatus,\n InsertHandler,\n UpdateHandler,\n DeleteHandler,\n StatusHandler,\n PD4ClientOptions,\n} from './types'\n\n// ---------------------------------------------------------------------------\n// Internal types for SSE handler registry\n// ---------------------------------------------------------------------------\n\ninterface TableHandlers {\n insert: InsertHandler[]\n update: UpdateHandler[]\n delete: DeleteHandler[]\n}\n\n// ---------------------------------------------------------------------------\n// PD4Client\n// ---------------------------------------------------------------------------\n\nexport class PD4Client {\n readonly url: string\n readonly db: string\n\n private EventSourceCtor: (new (url: string) => EventSource) | null\n private eventSource: EventSource | null = null\n private handlers = new Map<string, TableHandlers>()\n private statusHandlers: StatusHandler[] = []\n private _status: ConnectionStatus = 'connecting'\n\n constructor(url: string, db: string, options?: PD4ClientOptions) {\n this.url = url.replace(/\\/$/, '')\n this.db = db\n this.EventSourceCtor = options?.EventSource\n ?? (typeof globalThis !== 'undefined' && globalThis.EventSource\n ? globalThis.EventSource\n : null)\n }\n\n // --- URL helpers -------------------------------------------------------\n\n private get v1() {\n return `${this.url}/v1/${this.db}`\n }\n\n private get api() {\n return `${this.url}/api/${this.db}`\n }\n\n // --- HTTP helper -------------------------------------------------------\n\n private async request<T>(url: string, init?: RequestInit): Promise<T> {\n const res = await fetch(url, {\n ...init,\n headers: { 'Content-Type': 'application/json', ...init?.headers },\n })\n if (!res.ok) {\n const text = await res.text()\n throw new PD4Error(\n `PD4 ${init?.method ?? 'GET'} ${url}: ${res.status} ${text}`,\n res.status,\n url,\n )\n }\n if (res.status === 204) return undefined as T\n return res.json()\n }\n\n // --- Health ------------------------------------------------------------\n\n /** Check if PD4 is reachable */\n async ping(): Promise<boolean> {\n try {\n const res = await fetch(`${this.url}/health`)\n return res.ok\n } catch {\n return false\n }\n }\n\n // --- Database ----------------------------------------------------------\n\n /** Ensure the database is open */\n async ensureDatabase(): Promise<void> {\n await this.request(`${this.url}/v1/db`, {\n method: 'POST',\n body: JSON.stringify({ name: this.db }),\n })\n }\n\n // --- Tables ------------------------------------------------------------\n\n /** List all table names */\n async listTables(): Promise<string[]> {\n const data = await this.request<{ tables: string[] }>(`${this.v1}/tables`)\n return data.tables\n }\n\n /** Get table info */\n async getTable(name: string): Promise<TableInfo> {\n return this.request<TableInfo>(`${this.v1}/tables/${name}`)\n }\n\n /** Create a table (with auto_pk) */\n async createTable(name: string): Promise<void> {\n await this.request(`${this.v1}/tables`, {\n method: 'POST',\n body: JSON.stringify({ name, auto_pk: true }),\n })\n }\n\n /** Drop a table */\n async dropTable(name: string): Promise<void> {\n await this.request(`${this.v1}/tables/${name}`, { method: 'DELETE' })\n }\n\n /** Add a column to a table */\n async addColumn(table: string, name: string, dtype: string): Promise<void> {\n await this.request(`${this.v1}/tables/${table}/columns`, {\n method: 'POST',\n body: JSON.stringify({ name, dtype }),\n })\n }\n\n // --- Rows (flat objects in, flat objects out) ---------------------------\n\n /** Insert one or more rows (flat objects). Returns keys and count. */\n async insert(table: string, rows: Row | Row[]): Promise<InsertResult> {\n const arr = Array.isArray(rows) ? rows : [rows]\n const { columns, rows: colRows } = toColumnar(arr)\n return this.request<InsertResult>(`${this.v1}/tables/${table}/rows`, {\n method: 'POST',\n body: JSON.stringify({ columns, rows: colRows }),\n })\n }\n\n /** Update a single row by key with a flat object of changed columns. */\n async update(table: string, key: number, values: Row): Promise<void> {\n const pairs = toColumnValues(values)\n await this.request(`${this.v1}/views/${table}/rows/update`, {\n method: 'POST',\n body: JSON.stringify({ key, values: pairs }),\n })\n }\n\n /** Delete rows by keys. */\n async delete(table: string, keys: number | number[]): Promise<void> {\n const arr = Array.isArray(keys) ? keys : [keys]\n await this.request(`${this.v1}/views/${table}/rows/delete`, {\n method: 'POST',\n body: JSON.stringify({ keys: arr }),\n })\n }\n\n /** Fetch rows from a table/view. Returns flat Row objects. */\n async fetch(table: string, opts?: FetchOptions): Promise<FetchResult> {\n const offset = opts?.offset ?? 0\n const limit = opts?.limit ?? 1000\n const data = await this.request<{ rows: PD4Row[]; total: number }>(\n `${this.v1}/views/${table}/rows?offset=${offset}&limit=${limit}`,\n )\n return {\n rows: data.rows.map(flattenRow),\n total: data.total,\n }\n }\n\n // --- Raw row access (PD4 wire format) ----------------------------------\n\n /** Insert rows in columnar format (low-level). */\n async insertColumnar(\n table: string,\n columns: string[],\n rows: (string | number | boolean | null)[][],\n ): Promise<InsertResult> {\n return this.request<InsertResult>(`${this.v1}/tables/${table}/rows`, {\n method: 'POST',\n body: JSON.stringify({ columns, rows }),\n })\n }\n\n /** Update a row by key with column-value pairs (low-level). */\n async updateRaw(\n table: string,\n key: number,\n values: { column: string; value: string | number | boolean | null }[],\n ): Promise<void> {\n await this.request(`${this.v1}/views/${table}/rows/update`, {\n method: 'POST',\n body: JSON.stringify({ key, values }),\n })\n }\n\n /** Fetch rows in PD4 wire format (low-level). */\n async fetchRaw(\n table: string,\n offset = 0,\n limit = 1000,\n ): Promise<{ rows: PD4Row[]; total: number }> {\n return this.request(`${this.v1}/views/${table}/rows?offset=${offset}&limit=${limit}`)\n }\n\n // --- Buffer ------------------------------------------------------------\n\n /** Create a buffered view wrapping a table. */\n async buffer(table: string): Promise<PD4Buffer> {\n const info = await this.request<{ handle: string; source: string; row_count: number }>(\n `${this.v1}/views/${table}/buffer`,\n { method: 'POST' },\n )\n return new PD4Buffer(this, info.handle, table)\n }\n\n // --- SSE ---------------------------------------------------------------\n\n /** Get current SSE connection status. */\n get status(): ConnectionStatus {\n return this._status\n }\n\n /** Connect to the SSE event stream. Called automatically on first on(). */\n connect(): void {\n if (this.eventSource) return\n if (!this.EventSourceCtor) {\n throw new Error(\n 'EventSource is not available. In Node.js, pass { EventSource } from the \"eventsource\" package to the PD4Client constructor.',\n )\n }\n\n this._setStatus('connecting')\n const sse = new this.EventSourceCtor(`${this.api}/events`)\n this.eventSource = sse\n\n sse.addEventListener('session', () => {\n this._setStatus('connected')\n })\n\n sse.addEventListener('insert', (e: MessageEvent) => {\n const data = JSON.parse(e.data)\n const table = data.handle as string\n const keys: number[] = data.keys ?? []\n const newValues: Row[] = data.new_values ?? []\n this._dispatch(table, 'insert', keys, newValues, [])\n })\n\n sse.addEventListener('update', (e: MessageEvent) => {\n const data = JSON.parse(e.data)\n const table = data.handle as string\n const keys: number[] = data.keys ?? []\n const newValues: Row[] = data.new_values ?? []\n const oldValues: Row[] = data.old_values ?? []\n this._dispatch(table, 'update', keys, newValues, oldValues)\n })\n\n sse.addEventListener('delete', (e: MessageEvent) => {\n const data = JSON.parse(e.data)\n const table = data.handle as string\n const keys: number[] = data.keys ?? []\n this._dispatch(table, 'delete', keys, [], [])\n })\n\n sse.onerror = () => {\n this._setStatus('error')\n }\n }\n\n /** Disconnect from the SSE event stream. */\n disconnect(): void {\n this.eventSource?.close()\n this.eventSource = null\n this._setStatus('connecting')\n }\n\n /**\n * Subscribe to SSE events for a table.\n * Auto-connects on first call. Returns an unsubscribe function.\n */\n on(table: string, event: 'insert', handler: InsertHandler): () => void\n on(table: string, event: 'update', handler: UpdateHandler): () => void\n on(table: string, event: 'delete', handler: DeleteHandler): () => void\n on(\n table: string,\n event: 'insert' | 'update' | 'delete',\n handler: InsertHandler | UpdateHandler | DeleteHandler,\n ): () => void {\n // Auto-connect\n if (!this.eventSource) this.connect()\n\n let tableHandlers = this.handlers.get(table)\n if (!tableHandlers) {\n tableHandlers = { insert: [], update: [], delete: [] }\n this.handlers.set(table, tableHandlers)\n }\n\n const list = tableHandlers[event] as unknown[]\n list.push(handler)\n\n return () => {\n const idx = list.indexOf(handler)\n if (idx >= 0) list.splice(idx, 1)\n }\n }\n\n /** Subscribe to connection status changes. Returns an unsubscribe function. */\n onStatus(handler: StatusHandler): () => void {\n this.statusHandlers.push(handler)\n return () => {\n const idx = this.statusHandlers.indexOf(handler)\n if (idx >= 0) this.statusHandlers.splice(idx, 1)\n }\n }\n\n // --- SSE internals -----------------------------------------------------\n\n private _setStatus(status: ConnectionStatus) {\n this._status = status\n for (const handler of this.statusHandlers) {\n handler(status)\n }\n }\n\n private _dispatch(\n table: string,\n event: 'insert' | 'update' | 'delete',\n keys: number[],\n newValues: Row[],\n oldValues: Row[],\n ) {\n const tableHandlers = this.handlers.get(table)\n if (!tableHandlers) return\n\n if (event === 'insert') {\n for (const h of tableHandlers.insert) h(keys, newValues)\n } else if (event === 'update') {\n for (const h of tableHandlers.update) h(keys, newValues, oldValues)\n } else {\n for (const h of tableHandlers.delete) h(keys)\n }\n }\n}\n\n// Re-export for convenience\nexport type { ColumnInfo, TableInfo, PD4Row, Row, FetchOptions, FetchResult, InsertResult }\n","import { useEffect, useRef } from 'react'\nimport { usePD4 } from './context'\nimport type { InsertHandler, UpdateHandler, DeleteHandler } from '../types'\n\n/**\n * Subscribe to SSE events for a table. Auto-cleans up on unmount.\n *\n * Usage:\n * usePD4Subscribe('metrics', 'insert', (keys, rows) => { ... })\n * usePD4Subscribe('metrics', 'update', (keys, newVals, oldVals) => { ... })\n * usePD4Subscribe('metrics', 'delete', (keys) => { ... })\n */\nexport function usePD4Subscribe(table: string, event: 'insert', handler: InsertHandler): void\nexport function usePD4Subscribe(table: string, event: 'update', handler: UpdateHandler): void\nexport function usePD4Subscribe(table: string, event: 'delete', handler: DeleteHandler): void\nexport function usePD4Subscribe(\n table: string,\n event: 'insert' | 'update' | 'delete',\n handler: InsertHandler | UpdateHandler | DeleteHandler,\n): void {\n const db = usePD4()\n const handlerRef = useRef(handler)\n handlerRef.current = handler\n\n useEffect(() => {\n const wrapper = (...args: unknown[]) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ;(handlerRef.current as any)(...args)\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return db.on(table, event as any, wrapper as any)\n }, [db, table, event])\n}\n","import { useState, useEffect, useCallback, useRef } from 'react'\nimport { usePD4 } from './context'\nimport type { Row, ColumnInfo, ConnectionStatus } from '../types'\n\nconst HIGHLIGHT_MS = 1500\n\nexport interface UsePD4TableOptions {\n limit?: number\n deleteDelay?: number\n}\n\nexport interface UsePD4TableResult {\n rows: Row[]\n total: number\n columns: ColumnInfo[]\n status: ConnectionStatus\n highlights: Record<number, string>\n}\n\n/**\n * Full table state management hook.\n * Handles: initial fetch, SSE subscriptions for insert/update/delete,\n * row state management, highlight tracking, and buffer-commit edge cases.\n */\nexport function usePD4Table(\n table: string,\n opts?: UsePD4TableOptions,\n): UsePD4TableResult {\n const db = usePD4()\n const limit = opts?.limit ?? 1000\n const deleteDelay = opts?.deleteDelay ?? HIGHLIGHT_MS\n\n const [rows, setRows] = useState<Row[]>([])\n const [total, setTotal] = useState(0)\n const [columns, setColumns] = useState<ColumnInfo[]>([])\n const [status, setStatus] = useState<ConnectionStatus>('connecting')\n const [highlights, setHighlights] = useState<Record<number, string>>({})\n\n // Refs for stable callback access\n const tableRef = useRef(table)\n tableRef.current = table\n\n const highlightKeys = useCallback((keys: number[], type: string) => {\n if (keys.length === 0) return\n setHighlights((prev) => {\n const next = { ...prev }\n for (const k of keys) next[k] = type\n return next\n })\n setTimeout(() => {\n setHighlights((prev) => {\n const next = { ...prev }\n for (const k of keys) {\n if (next[k] === type) delete next[k]\n }\n return next\n })\n }, HIGHLIGHT_MS)\n }, [])\n\n const fetchRows = useCallback(async () => {\n try {\n const { rows: fetched, total: t } = await db.fetch(tableRef.current, { offset: 0, limit })\n setRows(fetched)\n setTotal(t)\n } catch {\n // Non-fatal\n }\n }, [db, limit])\n\n useEffect(() => {\n let cancelled = false\n const unsubs: (() => void)[] = []\n\n ;(async () => {\n try {\n // 1. Get column info\n const info = await db.getTable(table)\n if (cancelled) return\n setColumns(info.columns.filter((c) => c.name !== '_pk'))\n\n // 2. Fetch initial rows\n await fetchRows()\n if (cancelled) return\n setStatus('connected')\n\n // 3. SSE subscriptions\n unsubs.push(db.on(table, 'insert', (keys, newValues) => {\n if (cancelled) return\n const newRows = keys.map((k, i) => ({ _pk: k, ...newValues[i] }))\n setRows((prev) => [...prev, ...newRows])\n setTotal((prev) => prev + newRows.length)\n highlightKeys(keys, 'insert')\n }))\n\n unsubs.push(db.on(table, 'update', (keys, newValues) => {\n if (cancelled) return\n\n // Buffer commits send raw scalar values, not flat objects — fall back to refetch\n if (\n newValues.length === 0 ||\n typeof newValues[0] !== 'object' ||\n newValues[0] === null\n ) {\n fetchRows()\n highlightKeys(keys, 'update')\n return\n }\n\n const updateMap = new Map(keys.map((k, i) => [k, newValues[i]]))\n setRows((prev) =>\n prev.map((row) => {\n const changes = updateMap.get(row._pk as number)\n if (!changes) return row\n return { ...row, ...changes }\n }),\n )\n highlightKeys(keys, 'update')\n }))\n\n unsubs.push(db.on(table, 'delete', (keys) => {\n if (cancelled) return\n const keySet = new Set(keys)\n highlightKeys(keys, 'delete')\n setTimeout(() => {\n setRows((prev) => prev.filter((row) => !keySet.has(row._pk as number)))\n setTotal((prev) => Math.max(0, prev - keys.length))\n }, deleteDelay)\n }))\n } catch {\n if (!cancelled) {\n setStatus('error')\n }\n }\n })()\n\n return () => {\n cancelled = true\n for (const unsub of unsubs) unsub()\n }\n }, [db, table, limit, fetchRows, highlightKeys, deleteDelay])\n\n return { rows, total, columns, status, highlights }\n}\n","import { useState, useEffect } from 'react'\nimport { usePD4 } from './context'\nimport type { Row } from '../types'\n\nexport interface UsePD4QueryResult {\n rows: Row[]\n total: number\n loading: boolean\n error: string | null\n refetch: () => void\n}\n\n/**\n * One-shot query hook. Fetches rows from a table once (or on refetch).\n */\nexport function usePD4Query(\n table: string,\n offset = 0,\n limit = 1000,\n): UsePD4QueryResult {\n const db = usePD4()\n const [rows, setRows] = useState<Row[]>([])\n const [total, setTotal] = useState(0)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n const [attempt, setAttempt] = useState(0)\n\n useEffect(() => {\n let cancelled = false\n setLoading(true)\n setError(null)\n\n db.fetch(table, { offset, limit })\n .then((result) => {\n if (cancelled) return\n setRows(result.rows)\n setTotal(result.total)\n setLoading(false)\n })\n .catch((err) => {\n if (cancelled) return\n setError(err instanceof Error ? err.message : 'Query failed')\n setLoading(false)\n })\n\n return () => { cancelled = true }\n }, [db, table, offset, limit, attempt])\n\n return {\n rows,\n total,\n loading,\n error,\n refetch: () => setAttempt((a) => a + 1),\n }\n}\n"],"mappings":"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","names":["useRef","useRef","useEffect","useRef","useRef","useEffect","useState","useEffect","useState","useEffect"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@powerdata/pd4",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "JavaScript client library for PD4 — REST, SSE, and React hooks",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./react": {
|
|
16
|
+
"types": "./dist/react/index.d.ts",
|
|
17
|
+
"import": "./dist/react/index.js",
|
|
18
|
+
"require": "./dist/react/index.cjs"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": ["dist"],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsup",
|
|
24
|
+
"dev": "tsup --watch"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"react": ">=18"
|
|
28
|
+
},
|
|
29
|
+
"peerDependenciesMeta": {
|
|
30
|
+
"react": { "optional": true }
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"react": "^18.2.0",
|
|
34
|
+
"@types/react": "^18.2.0",
|
|
35
|
+
"tsup": "^8.0.0",
|
|
36
|
+
"typescript": "^5.3.0"
|
|
37
|
+
}
|
|
38
|
+
}
|