@xnetjs/react 0.1.2 → 0.3.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 +1 -1
- package/dist/index.js +6 -6
- 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
|
@@ -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';
|
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 {
|
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.3.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.3.0",
|
|
50
|
+
"@xnetjs/crypto": "0.3.0",
|
|
51
|
+
"@xnetjs/data": "0.3.0",
|
|
52
|
+
"@xnetjs/data-bridge": "0.3.0",
|
|
53
|
+
"@xnetjs/history": "0.3.0",
|
|
54
|
+
"@xnetjs/identity": "0.3.0",
|
|
55
|
+
"@xnetjs/plugins": "0.3.0",
|
|
56
|
+
"@xnetjs/runtime": "0.1.4",
|
|
57
|
+
"@xnetjs/sync": "0.3.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';
|