@xnetjs/react 0.2.0 → 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-EJ5RW5GI.js → chunk-BDBDZXYS.js} +1 -1
- package/dist/{chunk-6VOICQZ3.js → chunk-EJEGIEIC.js} +1 -1
- package/dist/{chunk-QHNYQVUM.js → chunk-Q3NDLI6Z.js} +2 -2
- package/dist/{chunk-7OQXRHEQ.js → chunk-QIX3F46C.js} +2 -2
- package/dist/{chunk-IHTMVTTE.js → chunk-RIN2MXZK.js} +435 -332
- package/dist/{chunk-KSHTDZ2V.js → chunk-WL7OCTSM.js} +1 -1
- package/dist/core.d.ts +2 -2
- package/dist/core.js +3 -3
- package/dist/database.js +2 -2
- package/dist/experimental.js +3 -3
- package/dist/index.d.ts +17 -4
- package/dist/index.js +45 -13
- package/dist/internal.d.ts +2 -2
- package/dist/internal.js +2 -2
- package/package.json +10 -10
- package/dist/{context-CFu9i136.d.ts → context-aeFzX2eW.d.ts} +1 -1
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
flattenNode,
|
|
3
3
|
useQuery,
|
|
4
4
|
useSyncManager
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-EJEGIEIC.js";
|
|
6
6
|
import {
|
|
7
7
|
useInstrumentation
|
|
8
8
|
} from "./chunk-JCOFKBOB.js";
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
useNodeStore,
|
|
12
12
|
useXNet,
|
|
13
13
|
useXNetInternal
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-RIN2MXZK.js";
|
|
15
15
|
|
|
16
16
|
// src/hooks/useInfiniteQuery.ts
|
|
17
17
|
import { createQueryDescriptor, serializeQueryDescriptor } from "@xnetjs/data-bridge";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useMutate,
|
|
3
3
|
useQuery
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-EJEGIEIC.js";
|
|
5
5
|
import {
|
|
6
6
|
XNetContext,
|
|
7
7
|
downloadBackup,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
useNodeStore,
|
|
10
10
|
useSecurityContext,
|
|
11
11
|
useXNet
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-RIN2MXZK.js";
|
|
13
13
|
|
|
14
14
|
// src/hooks/useTaskProjectionSync.ts
|
|
15
15
|
import { ExternalReferenceSchema, TaskSchema, isCompletedTaskStatus } from "@xnetjs/data";
|
|
@@ -227,153 +227,11 @@ function createRuntimeStatus(runtime, overrides = {}) {
|
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
// src/context.ts
|
|
230
|
-
import { MemoryNodeStorageAdapter, NodeStore } from "@xnetjs/data";
|
|
231
|
-
import {
|
|
232
|
-
createDataBridge,
|
|
233
|
-
createMainThreadBridge,
|
|
234
|
-
MainThreadBridge,
|
|
235
|
-
WorkerBridge
|
|
236
|
-
} from "@xnetjs/data-bridge";
|
|
237
230
|
import { UndoManager } from "@xnetjs/history";
|
|
238
|
-
import { createUCAN } from "@xnetjs/identity";
|
|
239
231
|
import { PluginRegistry } from "@xnetjs/plugins";
|
|
240
|
-
import React, {
|
|
241
|
-
createContext as createContext5,
|
|
242
|
-
useCallback,
|
|
243
|
-
useContext as useContext5,
|
|
244
|
-
useEffect as useEffect3,
|
|
245
|
-
useMemo as useMemo2,
|
|
246
|
-
useRef,
|
|
247
|
-
useState as useState3
|
|
248
|
-
} from "react";
|
|
249
|
-
|
|
250
|
-
// src/hub/auto-backup.ts
|
|
251
|
-
import * as Y from "yjs";
|
|
252
|
-
var AutoBackup = class {
|
|
253
|
-
constructor(upload, options) {
|
|
254
|
-
this.upload = upload;
|
|
255
|
-
this.debounceMs = options?.debounceMs ?? 5e3;
|
|
256
|
-
this.isEnabled = options?.isEnabled ?? (() => true);
|
|
257
|
-
}
|
|
258
|
-
timers = /* @__PURE__ */ new Map();
|
|
259
|
-
debounceMs;
|
|
260
|
-
isEnabled;
|
|
261
|
-
handleDocUpdate(docId, doc) {
|
|
262
|
-
this.scheduleBackup(docId, doc, this.debounceMs);
|
|
263
|
-
}
|
|
264
|
-
handleDocEvict(docId, doc) {
|
|
265
|
-
this.scheduleBackup(docId, doc, 0);
|
|
266
|
-
}
|
|
267
|
-
scheduleBackup(docId, doc, delay) {
|
|
268
|
-
const existing = this.timers.get(docId);
|
|
269
|
-
if (existing) {
|
|
270
|
-
clearTimeout(existing);
|
|
271
|
-
}
|
|
272
|
-
const run = async () => {
|
|
273
|
-
this.timers.delete(docId);
|
|
274
|
-
if (!this.isEnabled()) return;
|
|
275
|
-
try {
|
|
276
|
-
const state = Y.encodeStateAsUpdate(doc);
|
|
277
|
-
await this.upload(docId, state);
|
|
278
|
-
} catch (err) {
|
|
279
|
-
console.warn(`[auto-backup] Failed for ${docId}:`, err);
|
|
280
|
-
}
|
|
281
|
-
};
|
|
282
|
-
if (delay <= 0) {
|
|
283
|
-
void run();
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
this.timers.set(
|
|
287
|
-
docId,
|
|
288
|
-
setTimeout(() => void run(), delay)
|
|
289
|
-
);
|
|
290
|
-
}
|
|
291
|
-
async flush() {
|
|
292
|
-
for (const timer of this.timers.values()) {
|
|
293
|
-
clearTimeout(timer);
|
|
294
|
-
}
|
|
295
|
-
this.timers.clear();
|
|
296
|
-
}
|
|
297
|
-
destroy() {
|
|
298
|
-
void this.flush();
|
|
299
|
-
}
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
// src/hub/backup.ts
|
|
303
|
-
import { concatBytes, decrypt, encrypt, NONCE_SIZE } from "@xnetjs/crypto";
|
|
304
|
-
var toHttpUrl = (hubUrl) => {
|
|
305
|
-
try {
|
|
306
|
-
const url = new URL(hubUrl);
|
|
307
|
-
if (url.protocol === "ws:") url.protocol = "http:";
|
|
308
|
-
if (url.protocol === "wss:") url.protocol = "https:";
|
|
309
|
-
return url.toString().replace(/\/$/, "");
|
|
310
|
-
} catch {
|
|
311
|
-
return hubUrl;
|
|
312
|
-
}
|
|
313
|
-
};
|
|
314
|
-
var encodeEncrypted = (encrypted) => concatBytes(encrypted.nonce, encrypted.ciphertext);
|
|
315
|
-
var decodeEncrypted = (payload) => {
|
|
316
|
-
const nonce = payload.slice(0, NONCE_SIZE);
|
|
317
|
-
const ciphertext = payload.slice(NONCE_SIZE);
|
|
318
|
-
return { nonce, ciphertext };
|
|
319
|
-
};
|
|
320
|
-
var resolveFetch = (fetchFn) => {
|
|
321
|
-
if (fetchFn) return fetchFn;
|
|
322
|
-
if (typeof fetch === "undefined") {
|
|
323
|
-
throw new Error("fetch is not available in this environment");
|
|
324
|
-
}
|
|
325
|
-
return fetch;
|
|
326
|
-
};
|
|
327
|
-
var buildAuthHeader = async (getAuthToken) => {
|
|
328
|
-
if (!getAuthToken) return null;
|
|
329
|
-
const token = await getAuthToken();
|
|
330
|
-
if (!token) return null;
|
|
331
|
-
return `Bearer ${token}`;
|
|
332
|
-
};
|
|
333
|
-
async function uploadBackup(config, docId, plaintext) {
|
|
334
|
-
const encrypted = encrypt(plaintext, config.encryptionKey);
|
|
335
|
-
const payload = encodeEncrypted(encrypted);
|
|
336
|
-
return uploadEncryptedBackup(config, docId, payload);
|
|
337
|
-
}
|
|
338
|
-
async function uploadEncryptedBackup(config, docId, payload) {
|
|
339
|
-
const httpUrl = toHttpUrl(config.hubUrl);
|
|
340
|
-
const fetcher = resolveFetch(config.fetchFn);
|
|
341
|
-
const authHeader = await buildAuthHeader(config.getAuthToken);
|
|
342
|
-
const res = await fetcher(`${httpUrl}/backup/${encodeURIComponent(docId)}`, {
|
|
343
|
-
method: "PUT",
|
|
344
|
-
headers: {
|
|
345
|
-
...authHeader ? { Authorization: authHeader } : {},
|
|
346
|
-
"Content-Type": "application/octet-stream"
|
|
347
|
-
},
|
|
348
|
-
body: payload
|
|
349
|
-
});
|
|
350
|
-
if (!res.ok) {
|
|
351
|
-
throw new Error(`Backup upload failed: ${res.status} ${res.statusText}`);
|
|
352
|
-
}
|
|
353
|
-
return res.json();
|
|
354
|
-
}
|
|
355
|
-
async function downloadBackup(config, docId) {
|
|
356
|
-
const payload = await downloadEncryptedBackup(config, docId);
|
|
357
|
-
if (!payload) return null;
|
|
358
|
-
const encrypted = decodeEncrypted(payload);
|
|
359
|
-
return decrypt(encrypted, config.encryptionKey);
|
|
360
|
-
}
|
|
361
|
-
async function downloadEncryptedBackup(config, docId) {
|
|
362
|
-
const httpUrl = toHttpUrl(config.hubUrl);
|
|
363
|
-
const fetcher = resolveFetch(config.fetchFn);
|
|
364
|
-
const authHeader = await buildAuthHeader(config.getAuthToken);
|
|
365
|
-
const res = await fetcher(`${httpUrl}/backup/${encodeURIComponent(docId)}`, {
|
|
366
|
-
headers: authHeader ? { Authorization: authHeader } : void 0
|
|
367
|
-
});
|
|
368
|
-
if (res.status === 404) return null;
|
|
369
|
-
if (!res.ok) {
|
|
370
|
-
throw new Error(`Backup download failed: ${res.status} ${res.statusText}`);
|
|
371
|
-
}
|
|
372
|
-
return new Uint8Array(await res.arrayBuffer());
|
|
373
|
-
}
|
|
232
|
+
import React, { createContext as createContext5, useContext as useContext5, useEffect as useEffect6, useMemo as useMemo2, useState as useState5 } from "react";
|
|
374
233
|
|
|
375
|
-
// src/
|
|
376
|
-
import { createSyncManager } from "@xnetjs/runtime";
|
|
234
|
+
// src/provider/debug.ts
|
|
377
235
|
function log(...args) {
|
|
378
236
|
if (typeof localStorage !== "undefined" && localStorage.getItem("xnet:sync:debug") === "true") {
|
|
379
237
|
console.log("[XNetProvider]", ...args);
|
|
@@ -385,16 +243,10 @@ function scheduleIdle(fn) {
|
|
|
385
243
|
if (typeof ric === "function") ric(fn);
|
|
386
244
|
else setTimeout(fn, 1e3);
|
|
387
245
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
if (!url || seen.has(url)) return false;
|
|
393
|
-
seen.add(url);
|
|
394
|
-
return true;
|
|
395
|
-
});
|
|
396
|
-
return urls;
|
|
397
|
-
}
|
|
246
|
+
|
|
247
|
+
// src/provider/use-hub-auth-token.ts
|
|
248
|
+
import { createUCAN } from "@xnetjs/identity";
|
|
249
|
+
import { useCallback } from "react";
|
|
398
250
|
var HUB_CAPABILITIES = [
|
|
399
251
|
{ with: "*", can: "hub/*" },
|
|
400
252
|
{ with: "*", can: "backup/*" },
|
|
@@ -403,7 +255,112 @@ var HUB_CAPABILITIES = [
|
|
|
403
255
|
{ with: "*", can: "index/*" }
|
|
404
256
|
];
|
|
405
257
|
var HUB_TOKEN_TTL_SECONDS = 60 * 60 * 24;
|
|
258
|
+
function useHubAuthToken(input) {
|
|
259
|
+
const { authorDID, signingKey, hubUrl, autoAuth, staticHubAuthToken } = input;
|
|
260
|
+
return useCallback(async () => {
|
|
261
|
+
if (staticHubAuthToken) return staticHubAuthToken;
|
|
262
|
+
if (!hubUrl || !autoAuth) return "";
|
|
263
|
+
if (!authorDID || !signingKey) {
|
|
264
|
+
throw new Error("Missing authorDID/signingKey for hub auth");
|
|
265
|
+
}
|
|
266
|
+
return createUCAN({
|
|
267
|
+
issuer: authorDID,
|
|
268
|
+
issuerKey: signingKey,
|
|
269
|
+
audience: hubUrl,
|
|
270
|
+
capabilities: HUB_CAPABILITIES,
|
|
271
|
+
expiration: Math.floor(Date.now() / 1e3) + HUB_TOKEN_TTL_SECONDS
|
|
272
|
+
});
|
|
273
|
+
}, [authorDID, autoAuth, signingKey, hubUrl, staticHubAuthToken]);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// src/provider/use-hub-search-index.ts
|
|
277
|
+
import { useEffect as useEffect3 } from "react";
|
|
406
278
|
var HUB_INDEX_DEBOUNCE_MS = 2e3;
|
|
279
|
+
async function resolveTagSearchText(store, tagIds) {
|
|
280
|
+
const names = await Promise.all(
|
|
281
|
+
tagIds.map(async (id) => {
|
|
282
|
+
const tag = await store.get(id).catch(() => null);
|
|
283
|
+
const name = tag?.properties?.name;
|
|
284
|
+
return typeof name === "string" && name ? `#${name}` : null;
|
|
285
|
+
})
|
|
286
|
+
);
|
|
287
|
+
const present = names.filter((entry) => entry !== null);
|
|
288
|
+
return present.length > 0 ? present.join(" ") : void 0;
|
|
289
|
+
}
|
|
290
|
+
function useHubSearchIndex(input) {
|
|
291
|
+
const { nodeStore, syncManager, hubUrl, enableSearchIndex } = input;
|
|
292
|
+
useEffect3(() => {
|
|
293
|
+
if (!nodeStore || !syncManager || !hubUrl || !enableSearchIndex) return;
|
|
294
|
+
const connection = syncManager.connection;
|
|
295
|
+
if (!connection) return;
|
|
296
|
+
const timers = /* @__PURE__ */ new Map();
|
|
297
|
+
const pending = /* @__PURE__ */ new Map();
|
|
298
|
+
const schedule = (docId, payload) => {
|
|
299
|
+
pending.set(docId, payload);
|
|
300
|
+
const existing = timers.get(docId);
|
|
301
|
+
if (existing) clearTimeout(existing);
|
|
302
|
+
timers.set(
|
|
303
|
+
docId,
|
|
304
|
+
setTimeout(() => {
|
|
305
|
+
timers.delete(docId);
|
|
306
|
+
const next = pending.get(docId);
|
|
307
|
+
pending.delete(docId);
|
|
308
|
+
if (!next) return;
|
|
309
|
+
if (connection.status !== "connected") return;
|
|
310
|
+
if (next.type === "remove") {
|
|
311
|
+
connection.sendRaw({ type: "index-remove", docId });
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
connection.sendRaw({
|
|
315
|
+
type: "index-update",
|
|
316
|
+
docId,
|
|
317
|
+
meta: next.meta,
|
|
318
|
+
...next.text !== void 0 ? { text: next.text } : {}
|
|
319
|
+
});
|
|
320
|
+
}, HUB_INDEX_DEBOUNCE_MS)
|
|
321
|
+
);
|
|
322
|
+
};
|
|
323
|
+
const handleChange = (event) => {
|
|
324
|
+
const node = event.node;
|
|
325
|
+
if (!node || node.deleted) {
|
|
326
|
+
schedule(event.change.payload.nodeId, { type: "remove" });
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
if (!node.schemaId) return;
|
|
330
|
+
const title = typeof node.properties.title === "string" ? node.properties.title : typeof node.properties.name === "string" ? node.properties.name : "";
|
|
331
|
+
const meta = { schemaIri: node.schemaId, title, properties: node.properties };
|
|
332
|
+
const tagIds = Array.isArray(node.properties.tags) ? node.properties.tags.filter((id) => typeof id === "string") : [];
|
|
333
|
+
if (tagIds.length === 0) {
|
|
334
|
+
schedule(node.id, { type: "update", meta });
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
void resolveTagSearchText(nodeStore, tagIds).then((text) => {
|
|
338
|
+
schedule(node.id, { type: "update", meta, ...text ? { text } : {} });
|
|
339
|
+
});
|
|
340
|
+
};
|
|
341
|
+
const unsubscribe = nodeStore.subscribe(handleChange);
|
|
342
|
+
return () => {
|
|
343
|
+
unsubscribe();
|
|
344
|
+
for (const timer of timers.values()) {
|
|
345
|
+
clearTimeout(timer);
|
|
346
|
+
}
|
|
347
|
+
timers.clear();
|
|
348
|
+
pending.clear();
|
|
349
|
+
};
|
|
350
|
+
}, [enableSearchIndex, hubUrl, nodeStore, syncManager]);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// src/provider/use-node-store-runtime.ts
|
|
354
|
+
import { MemoryNodeStorageAdapter, NodeStore } from "@xnetjs/data";
|
|
355
|
+
import { useEffect as useEffect4, useRef, useState as useState3 } from "react";
|
|
356
|
+
|
|
357
|
+
// src/provider/runtime-resolution.ts
|
|
358
|
+
import {
|
|
359
|
+
createDataBridge,
|
|
360
|
+
createMainThreadBridge,
|
|
361
|
+
MainThreadBridge,
|
|
362
|
+
WorkerBridge
|
|
363
|
+
} from "@xnetjs/data-bridge";
|
|
407
364
|
function getRuntimeErrorMessage(err) {
|
|
408
365
|
return err instanceof Error ? err.message : String(err);
|
|
409
366
|
}
|
|
@@ -433,17 +390,6 @@ function logRuntimeStatus(runtime, status) {
|
|
|
433
390
|
}
|
|
434
391
|
console.info("[XNetProvider] Runtime ready:", status);
|
|
435
392
|
}
|
|
436
|
-
async function resolveTagSearchText(store, tagIds) {
|
|
437
|
-
const names = await Promise.all(
|
|
438
|
-
tagIds.map(async (id) => {
|
|
439
|
-
const tag = await store.get(id).catch(() => null);
|
|
440
|
-
const name = tag?.properties?.name;
|
|
441
|
-
return typeof name === "string" && name ? `#${name}` : null;
|
|
442
|
-
})
|
|
443
|
-
);
|
|
444
|
-
const present = names.filter((entry) => entry !== null);
|
|
445
|
-
return present.length > 0 ? present.join(" ") : void 0;
|
|
446
|
-
}
|
|
447
393
|
function resolveRuntimeFailure(runtime, nodeStore, reason, bridgeOptions) {
|
|
448
394
|
if (runtime.fallback === "main-thread") {
|
|
449
395
|
return {
|
|
@@ -568,79 +514,33 @@ async function resolveRuntimeBridge(input) {
|
|
|
568
514
|
})
|
|
569
515
|
};
|
|
570
516
|
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
517
|
+
|
|
518
|
+
// src/provider/use-node-store-runtime.ts
|
|
519
|
+
function useNodeStoreRuntime(input) {
|
|
520
|
+
const {
|
|
521
|
+
authorDID,
|
|
522
|
+
signingKey,
|
|
523
|
+
nodeStorage,
|
|
524
|
+
dataBridge: configDataBridge,
|
|
525
|
+
remoteNodeQueryClient,
|
|
526
|
+
remoteNodeQueryRouting,
|
|
527
|
+
syncManager: configSyncManager,
|
|
528
|
+
telemetry,
|
|
529
|
+
hubUrl,
|
|
530
|
+
signalingUrls,
|
|
531
|
+
runtimeConfig,
|
|
532
|
+
runtimeWorkerUrlKey
|
|
533
|
+
} = input;
|
|
582
534
|
const [nodeStore, setNodeStore] = useState3(null);
|
|
583
535
|
const [nodeStoreReady, setNodeStoreReady] = useState3(false);
|
|
584
|
-
const [undoManager, setUndoManager] = useState3(null);
|
|
585
536
|
const [dataBridge, setDataBridge] = useState3(null);
|
|
586
|
-
const [syncManager, setSyncManager] = useState3(null);
|
|
587
|
-
const [hubStatus, setHubStatus] = useState3("disconnected");
|
|
588
|
-
const [pluginRegistry, setPluginRegistry] = useState3(null);
|
|
589
537
|
const nodeStorageRef = useRef(null);
|
|
590
|
-
const platform = config.platform ?? "web";
|
|
591
|
-
const authorDID = config.authorDID ?? config.identity?.did;
|
|
592
|
-
const hubUrl = config.hubUrl ?? null;
|
|
593
|
-
const signalingServersKey = (config.signalingServers ?? []).join("\n");
|
|
594
|
-
const signalingServers = useMemo2(
|
|
595
|
-
() => signalingServersKey ? signalingServersKey.split("\n") : [],
|
|
596
|
-
[signalingServersKey]
|
|
597
|
-
);
|
|
598
|
-
const signalingUrls = useMemo2(
|
|
599
|
-
() => resolveConfiguredSignalingUrls(hubUrl, signalingServers),
|
|
600
|
-
[hubUrl, signalingServers]
|
|
601
|
-
);
|
|
602
|
-
const hubOptions = config.hubOptions;
|
|
603
|
-
const autoAuth = hubOptions?.autoAuth ?? true;
|
|
604
|
-
const staticHubAuthToken = hubOptions?.authToken?.trim() ?? "";
|
|
605
|
-
const autoBackup = hubOptions?.autoBackup ?? false;
|
|
606
|
-
const backupDebounceMs = hubOptions?.backupDebounceMs ?? 5e3;
|
|
607
|
-
const enableSearchIndex = hubOptions?.enableSearchIndex ?? false;
|
|
608
|
-
const nodeSyncRoom = hubOptions?.nodeSyncRoom ?? authorDID ?? "default";
|
|
609
|
-
const encryptionKey = config.encryptionKey ?? null;
|
|
610
|
-
const runtimeWorkerUrlKey = config.runtime?.worker?.url ? String(config.runtime.worker.url) : "";
|
|
611
|
-
const runtimeConfig = useMemo2(
|
|
612
|
-
() => resolveRuntimeConfig(config.runtime, platform),
|
|
613
|
-
[
|
|
614
|
-
config.runtime?.mode,
|
|
615
|
-
config.runtime?.fallback,
|
|
616
|
-
config.runtime?.diagnostics,
|
|
617
|
-
config.runtime?.worker?.dbName,
|
|
618
|
-
config.runtime?.worker?.signalingUrl,
|
|
619
|
-
runtimeWorkerUrlKey,
|
|
620
|
-
platform
|
|
621
|
-
]
|
|
622
|
-
);
|
|
623
538
|
const [runtimeStatus, setRuntimeStatus] = useState3(
|
|
624
539
|
() => createRuntimeStatus(runtimeConfig)
|
|
625
540
|
);
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
if (!hubUrl || !autoAuth) return "";
|
|
629
|
-
if (!authorDID || !config.signingKey) {
|
|
630
|
-
throw new Error("Missing authorDID/signingKey for hub auth");
|
|
631
|
-
}
|
|
632
|
-
return createUCAN({
|
|
633
|
-
issuer: authorDID,
|
|
634
|
-
issuerKey: config.signingKey,
|
|
635
|
-
audience: hubUrl,
|
|
636
|
-
capabilities: HUB_CAPABILITIES,
|
|
637
|
-
expiration: Math.floor(Date.now() / 1e3) + HUB_TOKEN_TTL_SECONDS
|
|
638
|
-
});
|
|
639
|
-
}, [authorDID, autoAuth, config.signingKey, hubUrl, staticHubAuthToken]);
|
|
640
|
-
useEffect3(() => {
|
|
641
|
-
const nodeStorageAdapter = config.nodeStorage ?? new MemoryNodeStorageAdapter();
|
|
541
|
+
useEffect4(() => {
|
|
542
|
+
const nodeStorageAdapter = nodeStorage ?? new MemoryNodeStorageAdapter();
|
|
642
543
|
nodeStorageRef.current = nodeStorageAdapter;
|
|
643
|
-
const signingKey = config.signingKey;
|
|
644
544
|
setRuntimeStatus(createRuntimeStatus(runtimeConfig));
|
|
645
545
|
if (!authorDID || !signingKey) {
|
|
646
546
|
console.warn(
|
|
@@ -673,10 +573,10 @@ function XNetProvider({ config, children }) {
|
|
|
673
573
|
authorDID,
|
|
674
574
|
signingKey,
|
|
675
575
|
signalingUrl: signalingUrls[0],
|
|
676
|
-
dataBridge:
|
|
677
|
-
remoteNodeQueryClient
|
|
678
|
-
remoteNodeQueryRouting
|
|
679
|
-
syncManager:
|
|
576
|
+
dataBridge: configDataBridge,
|
|
577
|
+
remoteNodeQueryClient,
|
|
578
|
+
remoteNodeQueryRouting,
|
|
579
|
+
syncManager: configSyncManager
|
|
680
580
|
});
|
|
681
581
|
if (cancelled) {
|
|
682
582
|
if (resolvedRuntime.createdInternally && resolvedRuntime.bridge) {
|
|
@@ -685,16 +585,13 @@ function XNetProvider({ config, children }) {
|
|
|
685
585
|
return;
|
|
686
586
|
}
|
|
687
587
|
setRuntimeStatus(resolvedRuntime.status);
|
|
688
|
-
reportRuntimeStatus(
|
|
588
|
+
reportRuntimeStatus(telemetry, resolvedRuntime.status);
|
|
689
589
|
logRuntimeStatus(runtimeConfig, resolvedRuntime.status);
|
|
690
590
|
if (resolvedRuntime.status.phase !== "ready" || !resolvedRuntime.bridge) {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
requestedMode: resolvedRuntime.status.requestedMode
|
|
696
|
-
}
|
|
697
|
-
);
|
|
591
|
+
telemetry?.reportCrash(new Error(resolvedRuntime.status.reason ?? "Runtime failed"), {
|
|
592
|
+
codeNamespace: "react.runtime.initialize",
|
|
593
|
+
requestedMode: resolvedRuntime.status.requestedMode
|
|
594
|
+
});
|
|
698
595
|
setNodeStore(null);
|
|
699
596
|
setNodeStoreReady(false);
|
|
700
597
|
setDataBridge(null);
|
|
@@ -732,43 +629,197 @@ function XNetProvider({ config, children }) {
|
|
|
732
629
|
};
|
|
733
630
|
}, [
|
|
734
631
|
authorDID,
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
632
|
+
nodeStorage,
|
|
633
|
+
signingKey,
|
|
634
|
+
configDataBridge,
|
|
738
635
|
signalingUrls,
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
636
|
+
configSyncManager,
|
|
637
|
+
remoteNodeQueryClient,
|
|
638
|
+
remoteNodeQueryRouting,
|
|
639
|
+
telemetry,
|
|
743
640
|
hubUrl,
|
|
744
641
|
runtimeConfig,
|
|
745
642
|
runtimeWorkerUrlKey
|
|
746
643
|
]);
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
644
|
+
return { nodeStore, nodeStoreReady, dataBridge, runtimeStatus, nodeStorageRef };
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// src/provider/use-sync-manager.ts
|
|
648
|
+
import { createSyncManager } from "@xnetjs/runtime";
|
|
649
|
+
import { useEffect as useEffect5, useState as useState4 } from "react";
|
|
650
|
+
|
|
651
|
+
// src/hub/auto-backup.ts
|
|
652
|
+
import * as Y from "yjs";
|
|
653
|
+
var AutoBackup = class {
|
|
654
|
+
constructor(upload, options) {
|
|
655
|
+
this.upload = upload;
|
|
656
|
+
this.debounceMs = options?.debounceMs ?? 5e3;
|
|
657
|
+
this.isEnabled = options?.isEnabled ?? (() => true);
|
|
658
|
+
}
|
|
659
|
+
timers = /* @__PURE__ */ new Map();
|
|
660
|
+
debounceMs;
|
|
661
|
+
isEnabled;
|
|
662
|
+
handleDocUpdate(docId, doc) {
|
|
663
|
+
this.scheduleBackup(docId, doc, this.debounceMs);
|
|
664
|
+
}
|
|
665
|
+
handleDocEvict(docId, doc) {
|
|
666
|
+
this.scheduleBackup(docId, doc, 0);
|
|
667
|
+
}
|
|
668
|
+
scheduleBackup(docId, doc, delay) {
|
|
669
|
+
const existing = this.timers.get(docId);
|
|
670
|
+
if (existing) {
|
|
671
|
+
clearTimeout(existing);
|
|
672
|
+
}
|
|
673
|
+
const run = async () => {
|
|
674
|
+
this.timers.delete(docId);
|
|
675
|
+
if (!this.isEnabled()) return;
|
|
676
|
+
try {
|
|
677
|
+
const state = Y.encodeStateAsUpdate(doc);
|
|
678
|
+
await this.upload(docId, state);
|
|
679
|
+
} catch (err) {
|
|
680
|
+
console.warn(`[auto-backup] Failed for ${docId}:`, err);
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
if (delay <= 0) {
|
|
684
|
+
void run();
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
this.timers.set(
|
|
688
|
+
docId,
|
|
689
|
+
setTimeout(() => void run(), delay)
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
async flush() {
|
|
693
|
+
for (const timer of this.timers.values()) {
|
|
694
|
+
clearTimeout(timer);
|
|
695
|
+
}
|
|
696
|
+
this.timers.clear();
|
|
697
|
+
}
|
|
698
|
+
destroy() {
|
|
699
|
+
void this.flush();
|
|
700
|
+
}
|
|
701
|
+
};
|
|
702
|
+
|
|
703
|
+
// src/hub/backup.ts
|
|
704
|
+
import { concatBytes, decrypt, encrypt, NONCE_SIZE } from "@xnetjs/crypto";
|
|
705
|
+
var toHttpUrl = (hubUrl) => {
|
|
706
|
+
try {
|
|
707
|
+
const url = new URL(hubUrl);
|
|
708
|
+
if (url.protocol === "ws:") url.protocol = "http:";
|
|
709
|
+
if (url.protocol === "wss:") url.protocol = "https:";
|
|
710
|
+
return url.toString().replace(/\/$/, "");
|
|
711
|
+
} catch {
|
|
712
|
+
return hubUrl;
|
|
713
|
+
}
|
|
714
|
+
};
|
|
715
|
+
var encodeEncrypted = (encrypted) => concatBytes(encrypted.nonce, encrypted.ciphertext);
|
|
716
|
+
var decodeEncrypted = (payload) => {
|
|
717
|
+
const nonce = payload.slice(0, NONCE_SIZE);
|
|
718
|
+
const ciphertext = payload.slice(NONCE_SIZE);
|
|
719
|
+
return { nonce, ciphertext };
|
|
720
|
+
};
|
|
721
|
+
var resolveFetch = (fetchFn) => {
|
|
722
|
+
if (fetchFn) return fetchFn;
|
|
723
|
+
if (typeof fetch === "undefined") {
|
|
724
|
+
throw new Error("fetch is not available in this environment");
|
|
725
|
+
}
|
|
726
|
+
return fetch;
|
|
727
|
+
};
|
|
728
|
+
var buildAuthHeader = async (getAuthToken) => {
|
|
729
|
+
if (!getAuthToken) return null;
|
|
730
|
+
const token = await getAuthToken();
|
|
731
|
+
if (!token) return null;
|
|
732
|
+
return `Bearer ${token}`;
|
|
733
|
+
};
|
|
734
|
+
async function uploadBackup(config, docId, plaintext) {
|
|
735
|
+
const encrypted = encrypt(plaintext, config.encryptionKey);
|
|
736
|
+
const payload = encodeEncrypted(encrypted);
|
|
737
|
+
return uploadEncryptedBackup(config, docId, payload);
|
|
738
|
+
}
|
|
739
|
+
async function uploadEncryptedBackup(config, docId, payload) {
|
|
740
|
+
const httpUrl = toHttpUrl(config.hubUrl);
|
|
741
|
+
const fetcher = resolveFetch(config.fetchFn);
|
|
742
|
+
const authHeader = await buildAuthHeader(config.getAuthToken);
|
|
743
|
+
const res = await fetcher(`${httpUrl}/backup/${encodeURIComponent(docId)}`, {
|
|
744
|
+
method: "PUT",
|
|
745
|
+
headers: {
|
|
746
|
+
...authHeader ? { Authorization: authHeader } : {},
|
|
747
|
+
"Content-Type": "application/octet-stream"
|
|
748
|
+
},
|
|
749
|
+
body: payload
|
|
750
|
+
});
|
|
751
|
+
if (!res.ok) {
|
|
752
|
+
throw new Error(`Backup upload failed: ${res.status} ${res.statusText}`);
|
|
753
|
+
}
|
|
754
|
+
return res.json();
|
|
755
|
+
}
|
|
756
|
+
async function downloadBackup(config, docId) {
|
|
757
|
+
const payload = await downloadEncryptedBackup(config, docId);
|
|
758
|
+
if (!payload) return null;
|
|
759
|
+
const encrypted = decodeEncrypted(payload);
|
|
760
|
+
return decrypt(encrypted, config.encryptionKey);
|
|
761
|
+
}
|
|
762
|
+
async function downloadEncryptedBackup(config, docId) {
|
|
763
|
+
const httpUrl = toHttpUrl(config.hubUrl);
|
|
764
|
+
const fetcher = resolveFetch(config.fetchFn);
|
|
765
|
+
const authHeader = await buildAuthHeader(config.getAuthToken);
|
|
766
|
+
const res = await fetcher(`${httpUrl}/backup/${encodeURIComponent(docId)}`, {
|
|
767
|
+
headers: authHeader ? { Authorization: authHeader } : void 0
|
|
768
|
+
});
|
|
769
|
+
if (res.status === 404) return null;
|
|
770
|
+
if (!res.ok) {
|
|
771
|
+
throw new Error(`Backup download failed: ${res.status} ${res.statusText}`);
|
|
772
|
+
}
|
|
773
|
+
return new Uint8Array(await res.arrayBuffer());
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// src/provider/use-sync-manager.ts
|
|
777
|
+
function useSyncManagerLifecycle(input) {
|
|
778
|
+
const {
|
|
779
|
+
nodeStore,
|
|
780
|
+
nodeStoreReady,
|
|
781
|
+
nodeStorageRef,
|
|
782
|
+
externalSyncManager,
|
|
783
|
+
disableSyncManager,
|
|
784
|
+
signalingUrls,
|
|
785
|
+
authorDID,
|
|
786
|
+
signingKey,
|
|
787
|
+
sync,
|
|
788
|
+
blobStore,
|
|
789
|
+
hubUrl,
|
|
790
|
+
nodeSyncRoom,
|
|
791
|
+
autoAuth,
|
|
792
|
+
autoBackup,
|
|
793
|
+
backupDebounceMs,
|
|
794
|
+
encryptionKey,
|
|
795
|
+
getHubAuthToken
|
|
796
|
+
} = input;
|
|
797
|
+
const [syncManager, setSyncManager] = useState4(null);
|
|
798
|
+
useEffect5(() => {
|
|
799
|
+
if (externalSyncManager) {
|
|
800
|
+
setSyncManager(externalSyncManager);
|
|
801
|
+
const sm2 = externalSyncManager;
|
|
802
|
+
if (sm2.setIdentity && authorDID && signingKey) {
|
|
803
|
+
sm2.setIdentity(authorDID, signingKey);
|
|
753
804
|
}
|
|
754
805
|
if (sm2.configureReplication) {
|
|
755
|
-
sm2.configureReplication(
|
|
806
|
+
sm2.configureReplication(sync);
|
|
756
807
|
}
|
|
757
|
-
|
|
808
|
+
externalSyncManager.start().catch((err) => {
|
|
758
809
|
console.warn("[XNetProvider] External SyncManager failed to start:", err);
|
|
759
810
|
});
|
|
760
811
|
return () => {
|
|
761
|
-
|
|
812
|
+
externalSyncManager.stop().catch((err) => {
|
|
762
813
|
console.warn("[XNetProvider] External SyncManager failed to stop:", err);
|
|
763
814
|
});
|
|
764
815
|
setSyncManager(null);
|
|
765
816
|
};
|
|
766
817
|
}
|
|
767
|
-
if (!nodeStore || !nodeStoreReady ||
|
|
818
|
+
if (!nodeStore || !nodeStoreReady || disableSyncManager) {
|
|
768
819
|
log("SyncManager disabled or NodeStore not ready", {
|
|
769
820
|
nodeStore: !!nodeStore,
|
|
770
821
|
nodeStoreReady,
|
|
771
|
-
disableSyncManager
|
|
822
|
+
disableSyncManager
|
|
772
823
|
});
|
|
773
824
|
setSyncManager(null);
|
|
774
825
|
return;
|
|
@@ -779,7 +830,7 @@ function XNetProvider({ config, children }) {
|
|
|
779
830
|
return;
|
|
780
831
|
}
|
|
781
832
|
const signalingUrl = signalingUrls[0] ?? "";
|
|
782
|
-
if (autoAuth && hubUrl && (!authorDID || !
|
|
833
|
+
if (autoAuth && hubUrl && (!authorDID || !signingKey)) {
|
|
783
834
|
console.warn("[XNetProvider] Hub auth enabled but authorDID/signingKey missing");
|
|
784
835
|
}
|
|
785
836
|
if (autoBackup && (!hubUrl || !encryptionKey)) {
|
|
@@ -795,9 +846,9 @@ function XNetProvider({ config, children }) {
|
|
|
795
846
|
signalingUrl,
|
|
796
847
|
signalingUrls,
|
|
797
848
|
authorDID,
|
|
798
|
-
signingKey
|
|
799
|
-
replication:
|
|
800
|
-
blobStore
|
|
849
|
+
signingKey,
|
|
850
|
+
replication: sync,
|
|
851
|
+
blobStore,
|
|
801
852
|
nodeSyncRoom: hubUrl ? nodeSyncRoom : void 0,
|
|
802
853
|
getUCANToken: hubUrl ? getHubAuthToken : void 0,
|
|
803
854
|
onDocUpdate: enableAutoBackup ? (nodeId, doc) => {
|
|
@@ -845,11 +896,11 @@ function XNetProvider({ config, children }) {
|
|
|
845
896
|
}, [
|
|
846
897
|
nodeStore,
|
|
847
898
|
nodeStoreReady,
|
|
848
|
-
|
|
849
|
-
|
|
899
|
+
disableSyncManager,
|
|
900
|
+
externalSyncManager,
|
|
850
901
|
signalingUrls,
|
|
851
|
-
|
|
852
|
-
|
|
902
|
+
blobStore,
|
|
903
|
+
sync,
|
|
853
904
|
authorDID,
|
|
854
905
|
autoAuth,
|
|
855
906
|
autoBackup,
|
|
@@ -857,9 +908,14 @@ function XNetProvider({ config, children }) {
|
|
|
857
908
|
encryptionKey,
|
|
858
909
|
getHubAuthToken,
|
|
859
910
|
hubUrl,
|
|
860
|
-
nodeSyncRoom
|
|
911
|
+
nodeSyncRoom,
|
|
912
|
+
nodeStorageRef,
|
|
913
|
+
signingKey
|
|
861
914
|
]);
|
|
862
|
-
|
|
915
|
+
return syncManager;
|
|
916
|
+
}
|
|
917
|
+
function useBridgeSyncWiring(dataBridge, syncManager) {
|
|
918
|
+
useEffect5(() => {
|
|
863
919
|
if (!dataBridge || !syncManager) return;
|
|
864
920
|
const bridge = dataBridge;
|
|
865
921
|
if (typeof bridge.setSyncManager === "function") {
|
|
@@ -872,7 +928,10 @@ function XNetProvider({ config, children }) {
|
|
|
872
928
|
}
|
|
873
929
|
};
|
|
874
930
|
}, [dataBridge, syncManager]);
|
|
875
|
-
|
|
931
|
+
}
|
|
932
|
+
function useHubStatus(syncManager) {
|
|
933
|
+
const [hubStatus, setHubStatus] = useState4("disconnected");
|
|
934
|
+
useEffect5(() => {
|
|
876
935
|
if (!syncManager) {
|
|
877
936
|
setHubStatus("disconnected");
|
|
878
937
|
return;
|
|
@@ -882,66 +941,110 @@ function XNetProvider({ config, children }) {
|
|
|
882
941
|
setHubStatus(status);
|
|
883
942
|
});
|
|
884
943
|
}, [syncManager]);
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
944
|
+
return hubStatus;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
// src/context.ts
|
|
948
|
+
function resolveConfiguredSignalingUrls(hubUrl, signalingServers) {
|
|
949
|
+
const seen = /* @__PURE__ */ new Set();
|
|
950
|
+
const configured = hubUrl ? [hubUrl, ...signalingServers ?? []] : signalingServers ?? [];
|
|
951
|
+
const urls = configured.map((url) => url.trim()).filter((url) => {
|
|
952
|
+
if (!url || seen.has(url)) return false;
|
|
953
|
+
seen.add(url);
|
|
954
|
+
return true;
|
|
955
|
+
});
|
|
956
|
+
return urls;
|
|
957
|
+
}
|
|
958
|
+
var XNetContext = createContext5(null);
|
|
959
|
+
var XNetInternalContext = createContext5({
|
|
960
|
+
authorDID: null,
|
|
961
|
+
signingKey: null,
|
|
962
|
+
sync: void 0
|
|
963
|
+
});
|
|
964
|
+
var DataBridgeContext = createContext5(null);
|
|
965
|
+
function useDataBridge() {
|
|
966
|
+
return useContext5(DataBridgeContext);
|
|
967
|
+
}
|
|
968
|
+
function XNetProvider({ config, children }) {
|
|
969
|
+
const [undoManager, setUndoManager] = useState5(null);
|
|
970
|
+
const [pluginRegistry, setPluginRegistry] = useState5(null);
|
|
971
|
+
const platform = config.platform ?? "web";
|
|
972
|
+
const authorDID = config.authorDID ?? config.identity?.did;
|
|
973
|
+
const hubUrl = config.hubUrl ?? null;
|
|
974
|
+
const signalingServersKey = (config.signalingServers ?? []).join("\n");
|
|
975
|
+
const signalingServers = useMemo2(
|
|
976
|
+
() => signalingServersKey ? signalingServersKey.split("\n") : [],
|
|
977
|
+
[signalingServersKey]
|
|
978
|
+
);
|
|
979
|
+
const signalingUrls = useMemo2(
|
|
980
|
+
() => resolveConfiguredSignalingUrls(hubUrl, signalingServers),
|
|
981
|
+
[hubUrl, signalingServers]
|
|
982
|
+
);
|
|
983
|
+
const hubOptions = config.hubOptions;
|
|
984
|
+
const autoAuth = hubOptions?.autoAuth ?? true;
|
|
985
|
+
const staticHubAuthToken = hubOptions?.authToken?.trim() ?? "";
|
|
986
|
+
const autoBackup = hubOptions?.autoBackup ?? false;
|
|
987
|
+
const backupDebounceMs = hubOptions?.backupDebounceMs ?? 5e3;
|
|
988
|
+
const enableSearchIndex = hubOptions?.enableSearchIndex ?? false;
|
|
989
|
+
const nodeSyncRoom = hubOptions?.nodeSyncRoom ?? authorDID ?? "default";
|
|
990
|
+
const encryptionKey = config.encryptionKey ?? null;
|
|
991
|
+
const runtimeWorkerUrlKey = config.runtime?.worker?.url ? String(config.runtime.worker.url) : "";
|
|
992
|
+
const runtimeConfig = useMemo2(
|
|
993
|
+
() => resolveRuntimeConfig(config.runtime, platform),
|
|
994
|
+
[
|
|
995
|
+
config.runtime?.mode,
|
|
996
|
+
config.runtime?.fallback,
|
|
997
|
+
config.runtime?.diagnostics,
|
|
998
|
+
config.runtime?.worker?.dbName,
|
|
999
|
+
config.runtime?.worker?.signalingUrl,
|
|
1000
|
+
runtimeWorkerUrlKey,
|
|
1001
|
+
platform
|
|
1002
|
+
]
|
|
1003
|
+
);
|
|
1004
|
+
const getHubAuthToken = useHubAuthToken({
|
|
1005
|
+
authorDID,
|
|
1006
|
+
signingKey: config.signingKey,
|
|
1007
|
+
hubUrl,
|
|
1008
|
+
autoAuth,
|
|
1009
|
+
staticHubAuthToken
|
|
1010
|
+
});
|
|
1011
|
+
const { nodeStore, nodeStoreReady, dataBridge, runtimeStatus, nodeStorageRef } = useNodeStoreRuntime({
|
|
1012
|
+
authorDID,
|
|
1013
|
+
signingKey: config.signingKey,
|
|
1014
|
+
nodeStorage: config.nodeStorage,
|
|
1015
|
+
dataBridge: config.dataBridge,
|
|
1016
|
+
remoteNodeQueryClient: config.remoteNodeQueryClient,
|
|
1017
|
+
remoteNodeQueryRouting: config.remoteNodeQueryRouting,
|
|
1018
|
+
syncManager: config.syncManager,
|
|
1019
|
+
telemetry: config.telemetry,
|
|
1020
|
+
hubUrl,
|
|
1021
|
+
signalingUrls,
|
|
1022
|
+
runtimeConfig,
|
|
1023
|
+
runtimeWorkerUrlKey
|
|
1024
|
+
});
|
|
1025
|
+
const syncManager = useSyncManagerLifecycle({
|
|
1026
|
+
nodeStore,
|
|
1027
|
+
nodeStoreReady,
|
|
1028
|
+
nodeStorageRef,
|
|
1029
|
+
externalSyncManager: config.syncManager,
|
|
1030
|
+
disableSyncManager: config.disableSyncManager,
|
|
1031
|
+
signalingUrls,
|
|
1032
|
+
authorDID,
|
|
1033
|
+
signingKey: config.signingKey,
|
|
1034
|
+
sync: config.sync,
|
|
1035
|
+
blobStore: config.blobStore,
|
|
1036
|
+
hubUrl,
|
|
1037
|
+
nodeSyncRoom,
|
|
1038
|
+
autoAuth,
|
|
1039
|
+
autoBackup,
|
|
1040
|
+
backupDebounceMs,
|
|
1041
|
+
encryptionKey,
|
|
1042
|
+
getHubAuthToken
|
|
1043
|
+
});
|
|
1044
|
+
useBridgeSyncWiring(dataBridge, syncManager);
|
|
1045
|
+
const hubStatus = useHubStatus(syncManager);
|
|
1046
|
+
useHubSearchIndex({ nodeStore, syncManager, hubUrl, enableSearchIndex });
|
|
1047
|
+
useEffect6(() => {
|
|
945
1048
|
if (!nodeStore || !nodeStoreReady || config.disablePlugins) {
|
|
946
1049
|
log("PluginRegistry disabled or NodeStore not ready");
|
|
947
1050
|
setPluginRegistry(null);
|
|
@@ -965,7 +1068,7 @@ function XNetProvider({ config, children }) {
|
|
|
965
1068
|
setPluginRegistry(null);
|
|
966
1069
|
};
|
|
967
1070
|
}, [nodeStore, nodeStoreReady, config.disablePlugins, config.platform]);
|
|
968
|
-
|
|
1071
|
+
useEffect6(() => {
|
|
969
1072
|
if (!nodeStore || !nodeStoreReady || !authorDID) {
|
|
970
1073
|
setUndoManager(null);
|
|
971
1074
|
return;
|
package/dist/core.d.ts
CHANGED
|
@@ -5,11 +5,11 @@ import { QueryPageInfo } from '@xnetjs/data-bridge';
|
|
|
5
5
|
import { Awareness } from 'y-protocols/awareness';
|
|
6
6
|
import * as Y from 'yjs';
|
|
7
7
|
import { Identity } from '@xnetjs/identity';
|
|
8
|
-
export { f as XNetConfig, X as XNetContextValue, e as XNetProvider, g as XNetProviderProps, h as XNetRuntimeConfig, i as XNetRuntimeFallback, j as XNetRuntimeMode, k as XNetRuntimePhase, d as XNetRuntimeStatus, l as XNetRuntimeWorkerConfig, a as useXNet } from './context-
|
|
8
|
+
export { f as XNetConfig, X as XNetContextValue, e as XNetProvider, g as XNetProviderProps, h as XNetRuntimeConfig, i as XNetRuntimeFallback, j as XNetRuntimeMode, k as XNetRuntimePhase, d as XNetRuntimeStatus, l as XNetRuntimeWorkerConfig, a as useXNet } from './context-aeFzX2eW.js';
|
|
9
9
|
import { Component, ReactNode, ErrorInfo } from 'react';
|
|
10
10
|
import '@xnetjs/core';
|
|
11
|
-
import '@xnetjs/runtime';
|
|
12
11
|
import '@xnetjs/crypto';
|
|
12
|
+
import '@xnetjs/runtime';
|
|
13
13
|
import '@xnetjs/sync';
|
|
14
14
|
import '@xnetjs/history';
|
|
15
15
|
import '@xnetjs/plugins';
|
package/dist/core.js
CHANGED
|
@@ -5,16 +5,16 @@ import {
|
|
|
5
5
|
useInfiniteQuery,
|
|
6
6
|
useIsOffline,
|
|
7
7
|
useNode
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-Q3NDLI6Z.js";
|
|
9
9
|
import {
|
|
10
10
|
useMutate,
|
|
11
11
|
useQuery
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-EJEGIEIC.js";
|
|
13
13
|
import "./chunk-JCOFKBOB.js";
|
|
14
14
|
import {
|
|
15
15
|
XNetProvider,
|
|
16
16
|
useXNet
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-RIN2MXZK.js";
|
|
18
18
|
export {
|
|
19
19
|
ErrorBoundary,
|
|
20
20
|
OfflineIndicator,
|
package/dist/database.js
CHANGED
package/dist/experimental.js
CHANGED
|
@@ -73,14 +73,14 @@ import {
|
|
|
73
73
|
useUndo,
|
|
74
74
|
useVerification,
|
|
75
75
|
useVisibleComments
|
|
76
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-QIX3F46C.js";
|
|
77
77
|
import {
|
|
78
78
|
flattenNode,
|
|
79
79
|
flattenNodes,
|
|
80
80
|
flattenNodesWithSchemaCheck,
|
|
81
81
|
flattenUnknownSchemaNode,
|
|
82
82
|
useSyncManager
|
|
83
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-EJEGIEIC.js";
|
|
84
84
|
import {
|
|
85
85
|
InstrumentationContext,
|
|
86
86
|
useInstrumentation
|
|
@@ -104,7 +104,7 @@ import {
|
|
|
104
104
|
useTelemetryReporter,
|
|
105
105
|
useView,
|
|
106
106
|
useViews
|
|
107
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-RIN2MXZK.js";
|
|
108
108
|
|
|
109
109
|
// src/experimental.ts
|
|
110
110
|
import { WebSocketSyncProvider } from "@xnetjs/runtime";
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export { i as FlattenNodeOptions, M as MigrationWarning, c as QueryListResult, d
|
|
|
3
3
|
export { ErrorBoundary, ErrorBoundaryProps, InfiniteQueryFilter, InfiniteQueryPage, InfiniteQueryResult, MutateCreate, MutateDelete, MutateOp, MutateRestore, MutateUpdate, OfflineIndicator, OfflineIndicatorProps, PresenceUser, SyncStatus, UseIdentityResult, UseMutateResult, UseNodeOptions, UseNodeResult, useIdentity, useInfiniteQuery, useIsOffline, useMutate, useNode } from './core.js';
|
|
4
4
|
import { U as UseTaskProjectionSyncResult, T as TaskProjectionInput, a as TaskTreeItem } from './experimental-B2FrBnkV.js';
|
|
5
5
|
export { A as AddCommentOptions, a0 as AddReactionOptions, bm as AuthErrorScreen, aP as AuthTraceSummary, bl as AuthenticatingScreen, r as CommentNode, C as CommentThread, F as CommentVisibility, ad as CreateMessageRequestOptions, b7 as DemoBanner, b8 as DemoBannerProps, bb as DemoDataExpiredScreen, be as DemoLimits, bd as DemoModeState, b9 as DemoQuotaIndicator, ba as DemoQuotaIndicatorProps, bf as DemoUsage, b2 as DiscoveredPeer, aU as FileRef, ae as FirstContactAdmission, af as FirstContactDecision, ag as FirstContactDecisionInput, G as FirstContactMode, ah as FirstContactVisibility, aK as GrantConsentSummary, aL as GrantInput, bp as HubConnectScreen, aX as HubSearchOptions, aY as HubSearchResult, aZ as HubSearchState, b3 as HubStatusIndicator, bo as ImportIdentityScreen, I as InteractionPermission, ai as MessageRequestNode, aj as MessageRequestProperties, ak as MessageRequestStatus, M as ModeratedCommentNode, H as ModeratedCommentThread, J as ModerationFilterOptions, K as ModerationLabelSummary, bA as OnboardingContextValue, bD as OnboardingEvent, bj as OnboardingFlow, bB as OnboardingFlowProps, bE as OnboardingMachineContext, bh as OnboardingProvider, bz as OnboardingProviderProps, bF as OnboardingReducerState, bC as OnboardingState, P as PageTaskInput, e as PageTaskReferenceInput, bI as PageTasksPanel, bJ as PageTasksPanelProps, bW as PluginRegistryContext, L as PublicInteractionMode, N as PublicInteractionPolicySnapshot, O as PublicInteractionSurface, Q as PublicModerationMode, bv as QUICK_START_TEMPLATES, bG as QuickStartTemplate, a1 as ReactionCounterSnapshot, a2 as ReactionNode, a3 as ReactionType, bq as ReadyScreen, a$ as RemoteSchemaDefinition, b0 as RemoteSchemaState, R as ReplyContext, bQ as SecurityContextActions, bP as SecurityContextState, bR as SecurityContextValue, bM as SecurityProvider, bS as SecurityProviderProps, b4 as Skeleton, b6 as SkeletonProps, br as SmartWelcome, bs as SyncProgressOverlay, bH as SyncProgressOverlayProps, bK as TaskCollectionEmbed, bL as TaskCollectionEmbedProps, j as TaskProjectionHost, i as TaskProjectionReferenceInput, bn as UnsupportedBrowserScreen, aw as UseAuditOptions, av as UseAuditResult, aQ as UseAuthTraceResult, aS as UseBackupReturn, aA as UseBlameResult, aH as UseCanEditResult, aF as UseCanResult, p as UseCommentsOptions, q as UseCommentsResult, ay as UseDiffResult, aV as UseFileUploadReturn, b as UseFindOptions, c as UseFindResult, aM as UseGrantsResult, aq as UseHistoryResult, al as UseMessageRequestsOptions, am as UseMessageRequestsResult, S as UseModeratedThreadOptions, f as UsePageTaskSyncOptions, g as UsePageTaskSyncResult, a4 as UsePolicyFilteredReactionCountersOptions, a5 as UsePolicyFilteredReactionCountersResult, bU as UseSecurityOptions, bV as UseSecurityResult, k as UseTaskProjectionSyncOptions, m as UseTasksOptions, n as UseTasksResult, at as UseUndoOptions, as as UseUndoResult, aC as UseVerificationResult, V as UseVisibleCommentsOptions, W as UseVisibleCommentsResult, bk as WelcomeScreen, by as copyToClipboard, a7 as createConversationKey, bu as createInitialState, a8 as createMessageRequestProperties, v as createModerationLabelIndex, Y as createReactionCounterSnapshot, Z as dedupeReactions, aI as describeGrantConsent, w as evaluateCommentModeration, a9 as evaluateFirstContactDecision, x as evaluateInteractionPermission, aa as findLatestMessageRequest, bw as getPlatformAuthName, ab as hasAcceptedContact, b5 as injectSkeletonStyles, _ as isReactionVisible, y as moderateThread, bt as onboardingReducer, z as selectActiveInteractionPolicy, B as selectPublicInteractionMode, aN as summarizeAuthTrace, ac as summarizeMessageRequest, D as summarizeModerationLabel, E as summarizePublicInteractionPolicy, $ as summarizeReactionNode, bx as truncateDid, au as useAudit, aO as useAuthTrace, aR as useBackup, az as useBlame, aE as useCan, aG as useCanEdit, c7 as useCommand, c0 as useCommands, an as useCommentCount, ao as useCommentCounts, o as useComments, b_ as useContributions, bc as useDemoMode, ax as useDiff, c4 as useEditorExtensions, c5 as useEditorExtensionsSafe, aT as useFileUpload, u as useFind, aJ as useGrants, ap as useHistory, aW as useHubSearch, aD as useHubStatus, c3 as useImporters, a6 as useMessageRequests, t as useModeratedThread, bi as useOnboarding, d as usePageTaskSync, b1 as usePeerDiscovery, bX as usePluginRegistry, bY as usePluginRegistryOptional, bZ as usePlugins, X as usePolicyFilteredReactionCounters, a_ as useRemoteSchema, bT as useSecurity, bN as useSecurityContext, bO as useSecurityContextOptional, c2 as useSidebarItems, c1 as useSlashCommands, bg as useSyncManager, h as useTaskProjectionSync, l as useTasks, ar as useUndo, aB as useVerification, c6 as useView, b$ as useViews, s as useVisibleComments } from './experimental-B2FrBnkV.js';
|
|
6
|
-
import { SchemaIRI, Schema, SavedViewDescriptor, DefinedSchema, PropertyBuilder, QueryASTOrderBy, QueryASTPage, QueryASTValidationResult, QueryASTPlannerGate, QueryASTAggregateExecution, ExternalReferenceProvider, SavedViewFeedLayout, SavedViewFeedDensity, FieldType, FieldConfig, ViewType, FilterGroup, SortConfig, RowHeight, SummaryFunction, CellValue } from '@xnetjs/data';
|
|
6
|
+
import { SchemaIRI, Schema, SavedViewDescriptor, DefinedSchema, PropertyBuilder, QueryASTOrderBy, QueryASTPage, QueryASTValidationResult, QueryASTPlannerGate, QueryASTAggregateExecution, ExternalReferenceProvider, SavedViewFeedLayout, SavedViewFeedDensity, FieldType, FieldConfig, ViewType, FilterGroup, SortConfig, RowHeight, SummaryFunction, FormViewConfig, FormFieldRule, CellValue, FormSubmissionMeta } from '@xnetjs/data';
|
|
7
7
|
export { ColumnConfig, ColumnDefinition, ColumnType, SavedViewFeedDensity, SavedViewFeedLayout, ViewConfig, ViewType } from '@xnetjs/data';
|
|
8
8
|
import { QueryExecutionMode, QuerySourcePreference, QuerySearchFilter, QueryPageInfo, QueryMetadata } from '@xnetjs/data-bridge';
|
|
9
9
|
import { LucideIcon } from 'lucide-react';
|
|
@@ -12,7 +12,7 @@ export { DatabaseRow, DatabaseRowData, ReverseRelation, UseCellOptions, UseCellR
|
|
|
12
12
|
export { u as useNodeStore } from './useNodeStore-DTCSBF51.js';
|
|
13
13
|
export { BlobStoreForSync, ConnectionManager, ConnectionManagerConfig, ConnectionStatus, InitialSyncManager, InitialSyncMessage, METABRIDGE_ORIGIN, METABRIDGE_SEED_ORIGIN, MetaBridge, MultiHubConnectionManagerConfig, NodePool, NodePoolConfig, NodeStoreSyncProvider, NodeSyncResponse, OfflineQueue, OfflineQueueConfig, PoolEntryState, ProgressListener, QueueEntry, Registry, RegistryConfig, RegistryStorage, SerializedNodeChange, SyncManager, SyncManagerConfig, SyncStatus as SyncManagerStatus, SyncPhase, SyncProgress, SyncReconciliationOptions, SyncReconciliationReport, TrackedNode, WebSocketSyncProvider, WebSocketSyncProviderOptions, createConnectionManager, createInitialSyncManager, createMetaBridge, createMultiHubConnectionManager, createNodePool, createOfflineQueue, createRegistry, createSyncManager } from '@xnetjs/runtime';
|
|
14
14
|
import { Subscription, Customer, Invoice, Payment } from '@xnetjs/billing';
|
|
15
|
-
export { n as TRACE_STAGES, s as TracingAttributes, T as TracingContext, p as TracingHandle, o as TracingReporter, r as TracingRootKind, q as TracingSpanInput, f as XNetConfig, X as XNetContextValue, e as XNetProvider, g as XNetProviderProps, h as XNetRuntimeConfig, i as XNetRuntimeFallback, j as XNetRuntimeMode, k as XNetRuntimePhase, d as XNetRuntimeStatus, l as XNetRuntimeWorkerConfig, u as useDataBridge, m as useTracingReporter, a as useXNet } from './context-
|
|
15
|
+
export { n as TRACE_STAGES, s as TracingAttributes, T as TracingContext, p as TracingHandle, o as TracingReporter, r as TracingRootKind, q as TracingSpanInput, f as XNetConfig, X as XNetContextValue, e as XNetProvider, g as XNetProviderProps, h as XNetRuntimeConfig, i as XNetRuntimeFallback, j as XNetRuntimeMode, k as XNetRuntimePhase, d as XNetRuntimeStatus, l as XNetRuntimeWorkerConfig, u as useDataBridge, m as useTracingReporter, a as useXNet } from './context-aeFzX2eW.js';
|
|
16
16
|
export { I as InstrumentationContext, a as InstrumentationContextValue, Q as QueryTrackerLike, Y as YDocRegistryLike, u as useInstrumentation } from './instrumentation-CpIuG2y5.js';
|
|
17
17
|
export { a as TelemetryContext, T as TelemetryReporter, u as useTelemetryReporter } from './telemetry-context-B7r6H1KW.js';
|
|
18
18
|
import '@xnetjs/core';
|
|
@@ -520,12 +520,22 @@ interface GridViewModel {
|
|
|
520
520
|
rowHeight: RowHeight;
|
|
521
521
|
columnSummaries: Record<string, SummaryFunction>;
|
|
522
522
|
sortKey: string;
|
|
523
|
+
formConfig: FormViewConfig | null;
|
|
524
|
+
formRules: Record<string, FormFieldRule>;
|
|
525
|
+
formAccepting: boolean;
|
|
523
526
|
}
|
|
524
527
|
interface GridRowModel {
|
|
525
528
|
id: string;
|
|
526
529
|
sortKey: string;
|
|
527
530
|
cells: Record<string, CellValue>;
|
|
528
531
|
}
|
|
532
|
+
/** Options for `addRow` (exploration 0278: form submissions). */
|
|
533
|
+
interface AddRowOptions {
|
|
534
|
+
/** Explicit node id — deterministic ids make retried submissions upsert. */
|
|
535
|
+
id?: string;
|
|
536
|
+
/** Form-submission provenance stamped on the row. */
|
|
537
|
+
meta?: FormSubmissionMeta;
|
|
538
|
+
}
|
|
529
539
|
interface UseGridDatabaseOptions {
|
|
530
540
|
/** Active view ID (defaults to the first view) */
|
|
531
541
|
viewId?: string;
|
|
@@ -556,7 +566,7 @@ interface UseGridDatabaseResult {
|
|
|
556
566
|
rowId: string;
|
|
557
567
|
fieldId: string;
|
|
558
568
|
}>) => Promise<void>;
|
|
559
|
-
addRow: (afterRowId?: string, cells?: Record<string, CellValue
|
|
569
|
+
addRow: (afterRowId?: string, cells?: Record<string, CellValue>, opts?: AddRowOptions) => Promise<string | null>;
|
|
560
570
|
deleteRows: (rowIds: string[]) => Promise<void>;
|
|
561
571
|
moveRowToIndex: (rowId: string, targetIndex: number) => Promise<void>;
|
|
562
572
|
addField: (name: string, type: FieldType, config?: FieldConfig, opts?: {
|
|
@@ -576,6 +586,9 @@ interface UseGridDatabaseResult {
|
|
|
576
586
|
setGroupBy: (fieldId: string | null) => Promise<void>;
|
|
577
587
|
setRowHeight: (rowHeight: RowHeight) => Promise<void>;
|
|
578
588
|
setColumnSummary: (fieldId: string, fn: SummaryFunction) => Promise<void>;
|
|
589
|
+
setFormConfig: (config: FormViewConfig) => Promise<void>;
|
|
590
|
+
setFormRules: (rules: Record<string, FormFieldRule>) => Promise<void>;
|
|
591
|
+
setFormAccepting: (accepting: boolean) => Promise<void>;
|
|
579
592
|
addView: (name: string, type: ViewType) => Promise<string | null>;
|
|
580
593
|
renameView: (viewId: string, name: string) => Promise<void>;
|
|
581
594
|
removeView: (viewId: string) => Promise<void>;
|
|
@@ -680,4 +693,4 @@ declare function flattenTaskTree(items: TaskTreeItem[], depth?: number): Rendera
|
|
|
680
693
|
declare function formatTaskDueDate(timestamp: number | undefined): string | null;
|
|
681
694
|
declare function isTaskOverdue(timestamp: number | undefined, completed: boolean): boolean;
|
|
682
695
|
|
|
683
|
-
export { type CanvasTaskInput, type CheckoutOptions, FlatNode, type GridFieldModel, type GridOptionModel, type GridRowModel, type GridViewModel, QueryFilter, type RenderableTaskRow, type SavedViewCanvasProjectionNode, type SavedViewDateBrushSelection, type SavedViewDateBucketFieldSummary, type SavedViewDateBucketInterval, type SavedViewDateBucketSummary, type SavedViewFacetSelection, type SavedViewFacetSummary, type SavedViewFacetValueSummary, type SavedViewFeedEnrichmentAdapter, type SavedViewFeedEnrichmentEntry, type SavedViewInspectorItem, type SavedViewInspectorItemKind, type SavedViewLensDraft, type SavedViewPresentationMode, type SavedViewPrivacyChip, type SavedViewPrivacyChipTone, type SavedViewPrivacySummary, type SavedViewQueryOverride, type SavedViewQueryResult, SavedViewResultTable, type SavedViewResultTableProps, type SavedViewRowInspectorModel, SavedViewRunner, type SavedViewRunnerProps, type SavedViewSchemaRegistry, type SavedViewSortDirection, type SavedViewVisualCanvasProjectionRequest, SavedViewVisualFeed, type SavedViewVisualLayoutId, type SavedViewVisualLayoutOption, type SavedViewVisualPreviewCreator, type SavedViewVisualPreviewKind, type SavedViewVisualPreviewModel, type SavedViewVisualPreviewPrivacy, type SavedViewVisualPreviewRelationship, type SavedViewVisualTimelineBucket, type SavedViewVisualWorkspaceLayout, TaskProjectionInput, TaskTreeItem, type UseBillingResult, type UseCanvasTaskSyncOptions, type UseCanvasTaskSyncResult, type UseEffectiveSchemaResult, type UseGlobalUndoResult, type UseGridDatabaseOptions, type UseGridDatabaseResult, type UseSavedViewOptions, type UseSavedViewResult, UseTaskProjectionSyncResult, createSavedViewCanvasProjectionNodes, createSavedViewLensDraft, createSavedViewVisualCanvasProjectionRequest, createSavedViewVisualPreviewFingerprint, deriveCachedSavedViewVisualPreviews, deriveSavedViewColumns, deriveSavedViewDateBucketSummaries, deriveSavedViewFacetSummaries, deriveSavedViewPrivacyChips, deriveSavedViewRowInspector, deriveSavedViewTimelineBuckets, deriveSavedViewVisualPreview, deriveSavedViewVisualPreviews, filterSavedViewRowsByDateBrush, filterSavedViewRowsByFacets, flattenTaskTree, formatSavedViewCellValue, formatTaskDueDate, getSavedViewSensitiveResultWarning, hasSavedViewVisualPreviewSensitiveData, isSavedViewVisualPreviewEmbeddable, isTaskOverdue, mergeSavedViewFeedEnrichment, savedViewVisualPreviewIsSelfActor, useBilling, useCanvasTaskSync, useEffectiveSchema, useGlobalUndo, useGridDatabase, useSavedView };
|
|
696
|
+
export { type AddRowOptions, type CanvasTaskInput, type CheckoutOptions, FlatNode, type GridFieldModel, type GridOptionModel, type GridRowModel, type GridViewModel, QueryFilter, type RenderableTaskRow, type SavedViewCanvasProjectionNode, type SavedViewDateBrushSelection, type SavedViewDateBucketFieldSummary, type SavedViewDateBucketInterval, type SavedViewDateBucketSummary, type SavedViewFacetSelection, type SavedViewFacetSummary, type SavedViewFacetValueSummary, type SavedViewFeedEnrichmentAdapter, type SavedViewFeedEnrichmentEntry, type SavedViewInspectorItem, type SavedViewInspectorItemKind, type SavedViewLensDraft, type SavedViewPresentationMode, type SavedViewPrivacyChip, type SavedViewPrivacyChipTone, type SavedViewPrivacySummary, type SavedViewQueryOverride, type SavedViewQueryResult, SavedViewResultTable, type SavedViewResultTableProps, type SavedViewRowInspectorModel, SavedViewRunner, type SavedViewRunnerProps, type SavedViewSchemaRegistry, type SavedViewSortDirection, type SavedViewVisualCanvasProjectionRequest, SavedViewVisualFeed, type SavedViewVisualLayoutId, type SavedViewVisualLayoutOption, type SavedViewVisualPreviewCreator, type SavedViewVisualPreviewKind, type SavedViewVisualPreviewModel, type SavedViewVisualPreviewPrivacy, type SavedViewVisualPreviewRelationship, type SavedViewVisualTimelineBucket, type SavedViewVisualWorkspaceLayout, TaskProjectionInput, TaskTreeItem, type UseBillingResult, type UseCanvasTaskSyncOptions, type UseCanvasTaskSyncResult, type UseEffectiveSchemaResult, type UseGlobalUndoResult, type UseGridDatabaseOptions, type UseGridDatabaseResult, type UseSavedViewOptions, type UseSavedViewResult, UseTaskProjectionSyncResult, createSavedViewCanvasProjectionNodes, createSavedViewLensDraft, createSavedViewVisualCanvasProjectionRequest, createSavedViewVisualPreviewFingerprint, deriveCachedSavedViewVisualPreviews, deriveSavedViewColumns, deriveSavedViewDateBucketSummaries, deriveSavedViewFacetSummaries, deriveSavedViewPrivacyChips, deriveSavedViewRowInspector, deriveSavedViewTimelineBuckets, deriveSavedViewVisualPreview, deriveSavedViewVisualPreviews, filterSavedViewRowsByDateBrush, filterSavedViewRowsByFacets, flattenTaskTree, formatSavedViewCellValue, formatTaskDueDate, getSavedViewSensitiveResultWarning, hasSavedViewVisualPreviewSensitiveData, isSavedViewVisualPreviewEmbeddable, isTaskOverdue, mergeSavedViewFeedEnrichment, savedViewVisualPreviewIsSelfActor, useBilling, useCanvasTaskSync, useEffectiveSchema, useGlobalUndo, useGridDatabase, useSavedView };
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
useInfiniteQuery,
|
|
6
6
|
useIsOffline,
|
|
7
7
|
useNode
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-Q3NDLI6Z.js";
|
|
9
9
|
import {
|
|
10
10
|
useCell,
|
|
11
11
|
useDatabase,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
useDatabaseSchema,
|
|
15
15
|
useRelatedRows,
|
|
16
16
|
useReverseRelations
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-WL7OCTSM.js";
|
|
18
18
|
import {
|
|
19
19
|
AuthErrorScreen,
|
|
20
20
|
AuthenticatingScreen,
|
|
@@ -94,7 +94,7 @@ import {
|
|
|
94
94
|
useUndo,
|
|
95
95
|
useVerification,
|
|
96
96
|
useVisibleComments
|
|
97
|
-
} from "./chunk-
|
|
97
|
+
} from "./chunk-QIX3F46C.js";
|
|
98
98
|
import {
|
|
99
99
|
EMPTY_PAGE_INFO,
|
|
100
100
|
computeFallbackPageInfo,
|
|
@@ -106,10 +106,10 @@ import {
|
|
|
106
106
|
useMutate,
|
|
107
107
|
useQuery,
|
|
108
108
|
useSyncManager
|
|
109
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-EJEGIEIC.js";
|
|
110
110
|
import {
|
|
111
111
|
useUndoScope
|
|
112
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-BDBDZXYS.js";
|
|
113
113
|
import {
|
|
114
114
|
InstrumentationContext,
|
|
115
115
|
useInstrumentation
|
|
@@ -142,7 +142,7 @@ import {
|
|
|
142
142
|
useView,
|
|
143
143
|
useViews,
|
|
144
144
|
useXNet
|
|
145
|
-
} from "./chunk-
|
|
145
|
+
} from "./chunk-RIN2MXZK.js";
|
|
146
146
|
|
|
147
147
|
// src/hooks/useEffectiveSchema.ts
|
|
148
148
|
import {
|
|
@@ -4264,7 +4264,10 @@ function toViewModel(node) {
|
|
|
4264
4264
|
hiddenFields: node.hiddenFields ?? [],
|
|
4265
4265
|
rowHeight: asRowHeight(node.rowHeight),
|
|
4266
4266
|
columnSummaries: node.columnSummaries ?? {},
|
|
4267
|
-
sortKey: node.sortKey ?? ""
|
|
4267
|
+
sortKey: node.sortKey ?? "",
|
|
4268
|
+
formConfig: node.formConfig ?? null,
|
|
4269
|
+
formRules: node.formRules ?? {},
|
|
4270
|
+
formAccepting: node.formAccepting ?? true
|
|
4268
4271
|
};
|
|
4269
4272
|
}
|
|
4270
4273
|
function fieldsToColumnDefinitions(fields) {
|
|
@@ -4533,7 +4536,7 @@ function useGridDatabase(databaseId, options = {}) {
|
|
|
4533
4536
|
[updateRowProps]
|
|
4534
4537
|
);
|
|
4535
4538
|
const addRow = useCallback2(
|
|
4536
|
-
async (afterRowId, cells) => {
|
|
4539
|
+
async (afterRowId, cells, opts) => {
|
|
4537
4540
|
let sortKey;
|
|
4538
4541
|
if (afterRowId) {
|
|
4539
4542
|
const bySortKey = [...rows].sort((a, b) => compareSortKeys(a.sortKey, b.sortKey));
|
|
@@ -4553,11 +4556,16 @@ function useGridDatabase(databaseId, options = {}) {
|
|
|
4553
4556
|
for (const [fieldId, value] of Object.entries(cells ?? {})) {
|
|
4554
4557
|
cellProps[cellKey(fieldId)] = value;
|
|
4555
4558
|
}
|
|
4556
|
-
const node = await mutate.create(
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4559
|
+
const node = await mutate.create(
|
|
4560
|
+
DatabaseRowSchema,
|
|
4561
|
+
{
|
|
4562
|
+
database: databaseId,
|
|
4563
|
+
sortKey,
|
|
4564
|
+
...opts?.meta ? { submissionMeta: opts.meta } : {},
|
|
4565
|
+
...cellProps
|
|
4566
|
+
},
|
|
4567
|
+
opts?.id
|
|
4568
|
+
);
|
|
4561
4569
|
return node?.id ?? null;
|
|
4562
4570
|
},
|
|
4563
4571
|
[mutate, databaseId, rows, nextAppendKey]
|
|
@@ -4750,6 +4758,27 @@ function useGridDatabase(databaseId, options = {}) {
|
|
|
4750
4758
|
},
|
|
4751
4759
|
[mutate, activeView]
|
|
4752
4760
|
);
|
|
4761
|
+
const setFormConfig = useCallback2(
|
|
4762
|
+
async (config) => {
|
|
4763
|
+
if (!activeView) return;
|
|
4764
|
+
await mutate.update(DatabaseViewSchema, activeView.id, { formConfig: config });
|
|
4765
|
+
},
|
|
4766
|
+
[mutate, activeView]
|
|
4767
|
+
);
|
|
4768
|
+
const setFormRules = useCallback2(
|
|
4769
|
+
async (rules) => {
|
|
4770
|
+
if (!activeView) return;
|
|
4771
|
+
await mutate.update(DatabaseViewSchema, activeView.id, { formRules: rules });
|
|
4772
|
+
},
|
|
4773
|
+
[mutate, activeView]
|
|
4774
|
+
);
|
|
4775
|
+
const setFormAccepting = useCallback2(
|
|
4776
|
+
async (accepting) => {
|
|
4777
|
+
if (!activeView) return;
|
|
4778
|
+
await mutate.update(DatabaseViewSchema, activeView.id, { formAccepting: accepting });
|
|
4779
|
+
},
|
|
4780
|
+
[mutate, activeView]
|
|
4781
|
+
);
|
|
4753
4782
|
const addView = useCallback2(
|
|
4754
4783
|
async (name, type) => {
|
|
4755
4784
|
const node = await mutate.create(DatabaseViewSchema, {
|
|
@@ -4801,6 +4830,9 @@ function useGridDatabase(databaseId, options = {}) {
|
|
|
4801
4830
|
setGroupBy,
|
|
4802
4831
|
setRowHeight,
|
|
4803
4832
|
setColumnSummary,
|
|
4833
|
+
setFormConfig,
|
|
4834
|
+
setFormRules,
|
|
4835
|
+
setFormAccepting,
|
|
4804
4836
|
addView,
|
|
4805
4837
|
renameView,
|
|
4806
4838
|
removeView,
|
package/dist/internal.d.ts
CHANGED
|
@@ -3,13 +3,13 @@ import { DID } from '@xnetjs/core';
|
|
|
3
3
|
import { NodeId } from '@xnetjs/data';
|
|
4
4
|
import { UndoManagerOptions } from '@xnetjs/history';
|
|
5
5
|
export { I as InstrumentationContext, a as InstrumentationContextValue, Q as QueryTrackerLike, Y as YDocRegistryLike, u as useInstrumentation } from './instrumentation-CpIuG2y5.js';
|
|
6
|
-
export { X as XNetContextValue, c as XNetInternalContextValue, d as XNetRuntimeStatus, u as useDataBridge, a as useXNet, b as useXNetInternal } from './context-
|
|
6
|
+
export { X as XNetContextValue, c as XNetInternalContextValue, d as XNetRuntimeStatus, u as useDataBridge, a as useXNet, b as useXNetInternal } from './context-aeFzX2eW.js';
|
|
7
7
|
import 'react';
|
|
8
8
|
import '@xnetjs/data-bridge';
|
|
9
9
|
import 'yjs';
|
|
10
|
-
import '@xnetjs/runtime';
|
|
11
10
|
import '@xnetjs/crypto';
|
|
12
11
|
import '@xnetjs/identity';
|
|
12
|
+
import '@xnetjs/runtime';
|
|
13
13
|
import '@xnetjs/sync';
|
|
14
14
|
import '@xnetjs/plugins';
|
|
15
15
|
import './telemetry-context-B7r6H1KW.js';
|
package/dist/internal.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useUndoScope
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BDBDZXYS.js";
|
|
4
4
|
import {
|
|
5
5
|
InstrumentationContext,
|
|
6
6
|
useInstrumentation
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
useNodeStore,
|
|
11
11
|
useXNet,
|
|
12
12
|
useXNetInternal
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-RIN2MXZK.js";
|
|
14
14
|
export {
|
|
15
15
|
InstrumentationContext,
|
|
16
16
|
useDataBridge,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xnetjs/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -46,15 +46,15 @@
|
|
|
46
46
|
"y-protocols": "^1.0.6",
|
|
47
47
|
"yjs": "^13.6.24",
|
|
48
48
|
"@xnetjs/billing": "0.0.2",
|
|
49
|
-
"@xnetjs/core": "0.
|
|
50
|
-
"@xnetjs/crypto": "0.
|
|
51
|
-
"@xnetjs/data": "0.
|
|
52
|
-
"@xnetjs/data-bridge": "0.
|
|
53
|
-
"@xnetjs/history": "0.
|
|
54
|
-
"@xnetjs/identity": "0.
|
|
55
|
-
"@xnetjs/plugins": "0.
|
|
56
|
-
"@xnetjs/runtime": "0.1.
|
|
57
|
-
"@xnetjs/sync": "0.
|
|
49
|
+
"@xnetjs/core": "0.4.0",
|
|
50
|
+
"@xnetjs/crypto": "0.4.0",
|
|
51
|
+
"@xnetjs/data": "0.4.0",
|
|
52
|
+
"@xnetjs/data-bridge": "0.4.0",
|
|
53
|
+
"@xnetjs/history": "0.4.0",
|
|
54
|
+
"@xnetjs/identity": "0.4.0",
|
|
55
|
+
"@xnetjs/plugins": "0.4.0",
|
|
56
|
+
"@xnetjs/runtime": "0.1.5",
|
|
57
|
+
"@xnetjs/sync": "0.4.0"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"react": "^18.0.0 || ^19.0.0"
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { SyncManager, BlobStoreForSync, SyncStatus, ConnectionManager } from '@xnetjs/runtime';
|
|
2
1
|
import { DID } from '@xnetjs/core';
|
|
3
2
|
import { SecurityLevel } from '@xnetjs/crypto';
|
|
4
3
|
import { NodeStorageAdapter, NodeStore } from '@xnetjs/data';
|
|
5
4
|
import { Identity, PQKeyRegistry, HybridKeyBundle } from '@xnetjs/identity';
|
|
5
|
+
import { SyncManager, BlobStoreForSync, SyncStatus, ConnectionManager } from '@xnetjs/runtime';
|
|
6
6
|
import { SyncReplicationConfig } from '@xnetjs/sync';
|
|
7
7
|
import * as react from 'react';
|
|
8
8
|
import { ReactNode } from 'react';
|