jazz-tools 0.15.15 → 0.15.16

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.
Files changed (40) hide show
  1. package/.turbo/turbo-build.log +36 -40
  2. package/CHANGELOG.md +10 -0
  3. package/dist/{chunk-4CFNXQE7.js → chunk-OSVAAVWQ.js} +103 -6
  4. package/dist/chunk-OSVAAVWQ.js.map +1 -0
  5. package/dist/index.js +357 -3
  6. package/dist/index.js.map +1 -1
  7. package/dist/react/index.js +2 -0
  8. package/dist/react/index.js.map +1 -1
  9. package/dist/react/testing.js +3 -1
  10. package/dist/react/testing.js.map +1 -1
  11. package/dist/testing.js +1 -1
  12. package/dist/tools/coValues/group.d.ts +1 -0
  13. package/dist/tools/coValues/group.d.ts.map +1 -1
  14. package/dist/tools/coValues/inbox.d.ts.map +1 -1
  15. package/dist/tools/coValues/interfaces.d.ts +58 -2
  16. package/dist/tools/coValues/interfaces.d.ts.map +1 -1
  17. package/dist/tools/coValues/request.d.ts +82 -0
  18. package/dist/tools/coValues/request.d.ts.map +1 -0
  19. package/dist/tools/exports.d.ts +2 -1
  20. package/dist/tools/exports.d.ts.map +1 -1
  21. package/dist/tools/lib/id.d.ts +2 -0
  22. package/dist/tools/lib/id.d.ts.map +1 -0
  23. package/dist/tools/subscribe/SubscriptionScope.d.ts +3 -2
  24. package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
  25. package/dist/tools/tests/exportImport.test.d.ts +2 -0
  26. package/dist/tools/tests/exportImport.test.d.ts.map +1 -0
  27. package/dist/tools/tests/request.test.d.ts +2 -0
  28. package/dist/tools/tests/request.test.d.ts.map +1 -0
  29. package/package.json +6 -5
  30. package/src/tools/coValues/group.ts +1 -0
  31. package/src/tools/coValues/inbox.ts +4 -3
  32. package/src/tools/coValues/interfaces.ts +177 -2
  33. package/src/tools/coValues/request.ts +631 -0
  34. package/src/tools/exports.ts +8 -0
  35. package/src/tools/lib/id.ts +3 -0
  36. package/src/tools/subscribe/SubscriptionScope.ts +10 -1
  37. package/src/tools/tests/exportImport.test.ts +526 -0
  38. package/src/tools/tests/request.test.ts +951 -0
  39. package/tsup.config.ts +0 -2
  40. package/dist/chunk-4CFNXQE7.js.map +0 -1
@@ -1,6 +1,13 @@
1
- import type { CoValueUniqueness, RawCoValue } from "cojson";
2
1
  import {
3
- type Account,
2
+ CoValueCore,
3
+ type CoValueUniqueness,
4
+ type CojsonInternalTypes,
5
+ type RawCoValue,
6
+ emptyKnownState,
7
+ } from "cojson";
8
+ import { AvailableCoValueCore } from "cojson/dist/coValueCore/coValueCore.js";
9
+ import {
10
+ Account,
4
11
  AnonymousJazzAgent,
5
12
  CoValueOrZodSchema,
6
13
  type Group,
@@ -15,6 +22,7 @@ import {
15
22
  type SubscriptionValue,
16
23
  activeAccountContext,
17
24
  anySchemaToCoSchema,
25
+ getSubscriptionScope,
18
26
  inspect,
19
27
  } from "../internal.js";
20
28
 
@@ -462,3 +470,170 @@ export function parseGroupCreateOptions(
462
470
  ? { owner: options }
463
471
  : { owner: options.owner ?? activeAccountContext.get() };
464
472
  }
473
+
474
+ /**
475
+ * Deeply export a CoValue to a content piece.
476
+ *
477
+ * @param cls - The class of the CoValue to export.
478
+ * @param id - The ID of the CoValue to export.
479
+ * @param options - The options for the export.
480
+ * @returns The content pieces that were exported.
481
+ *
482
+ * @example
483
+ * ```ts
484
+ * const Address = co.map({
485
+ * street: z.string(),
486
+ * city: z.string(),
487
+ * });
488
+ *
489
+ * const Person = co.map({
490
+ * name: z.string(),
491
+ * address: Address,
492
+ * });
493
+ *
494
+ * const group = Group.create();
495
+ * const address = Address.create(
496
+ * { street: "123 Main St", city: "New York" },
497
+ * group,
498
+ * );
499
+ * const person = Person.create({ name: "John", address }, group);
500
+ * group.addMember("everyone", "reader");
501
+ *
502
+ * // Export with nested references resolved, values can be serialized to JSON
503
+ * const exportedWithResolve = await exportCoValue(Person, person.id, {
504
+ * resolve: { address: true },
505
+ * });
506
+ *
507
+ * // In another client or session
508
+ * // Load the exported content pieces into the node, they will be persisted
509
+ * importContentPieces(exportedWithResolve);
510
+ *
511
+ * // Now the person can be loaded from the node, even offline
512
+ * const person = await loadCoValue(Person, person.id, {
513
+ * resolve: { address: true },
514
+ * });
515
+ * ```
516
+ */
517
+ export async function exportCoValue<
518
+ S extends CoValueOrZodSchema | CoValueClass<CoValue>,
519
+ const R extends ResolveQuery<S>,
520
+ >(
521
+ cls: S,
522
+ id: ID<CoValue>,
523
+ options: {
524
+ resolve?: ResolveQueryStrict<S, R>;
525
+ loadAs: Account | AnonymousJazzAgent;
526
+ skipRetry?: boolean;
527
+ bestEffortResolution?: boolean;
528
+ },
529
+ ) {
530
+ const loadAs = options.loadAs ?? activeAccountContext.get();
531
+ const node = "node" in loadAs ? loadAs.node : loadAs._raw.core.node;
532
+
533
+ const resolve = options.resolve ?? true;
534
+
535
+ const rootNode = new SubscriptionScope<CoValue>(
536
+ node,
537
+ resolve as any,
538
+ id,
539
+ {
540
+ ref: anySchemaToCoSchema(cls),
541
+ optional: false,
542
+ },
543
+ options.skipRetry,
544
+ options.bestEffortResolution,
545
+ );
546
+
547
+ const value = await new Promise<Loaded<S, R> | null>((resolve) => {
548
+ rootNode.setListener((value) => {
549
+ if (value.type === "unavailable") {
550
+ resolve(null);
551
+ console.error(value.toString());
552
+ } else if (value.type === "unauthorized") {
553
+ resolve(null);
554
+ console.error(value.toString());
555
+ } else if (value.type === "loaded") {
556
+ resolve(value.value as Loaded<S, R>);
557
+ }
558
+
559
+ rootNode.destroy();
560
+ });
561
+ });
562
+
563
+ if (!value) {
564
+ return null;
565
+ }
566
+
567
+ const valuesExported = new Set<string>();
568
+ const contentPieces: CojsonInternalTypes.NewContentMessage[] = [];
569
+
570
+ loadContentPiecesFromSubscription(rootNode, valuesExported, contentPieces);
571
+
572
+ return contentPieces;
573
+ }
574
+
575
+ function loadContentPiecesFromSubscription(
576
+ subscription: SubscriptionScope<any>,
577
+ valuesExported: Set<string>,
578
+ contentPieces: CojsonInternalTypes.NewContentMessage[],
579
+ ) {
580
+ if (valuesExported.has(subscription.id)) {
581
+ return;
582
+ }
583
+
584
+ valuesExported.add(subscription.id);
585
+
586
+ const core = subscription.getCurrentValue()?._raw
587
+ .core as AvailableCoValueCore;
588
+
589
+ if (core) {
590
+ loadContentPiecesFromCoValue(core, valuesExported, contentPieces);
591
+ }
592
+
593
+ for (const child of subscription.childNodes.values()) {
594
+ loadContentPiecesFromSubscription(child, valuesExported, contentPieces);
595
+ }
596
+ }
597
+
598
+ function loadContentPiecesFromCoValue(
599
+ core: AvailableCoValueCore,
600
+ valuesExported: Set<string>,
601
+ contentPieces: CojsonInternalTypes.NewContentMessage[],
602
+ ) {
603
+ for (const dependency of core.getDependedOnCoValues()) {
604
+ if (valuesExported.has(dependency)) {
605
+ continue;
606
+ }
607
+
608
+ const depCoValue = core.node.getCoValue(dependency);
609
+
610
+ if (depCoValue.isAvailable()) {
611
+ valuesExported.add(dependency);
612
+ loadContentPiecesFromCoValue(depCoValue, valuesExported, contentPieces);
613
+ }
614
+ }
615
+
616
+ const pieces = core.verified.newContentSince(emptyKnownState(core.id));
617
+
618
+ for (const piece of pieces ?? []) {
619
+ contentPieces.push(piece);
620
+ }
621
+ }
622
+
623
+ /**
624
+ * Import content pieces into the node.
625
+ *
626
+ * @param contentPieces - The content pieces to import.
627
+ * @param loadAs - The account to load the content pieces as.
628
+ */
629
+ export function importContentPieces(
630
+ contentPieces: CojsonInternalTypes.NewContentMessage[],
631
+ loadAs?: Account | AnonymousJazzAgent,
632
+ ) {
633
+ const account = loadAs ?? Account.getMe();
634
+ const node = "node" in account ? account.node : account._raw.core.node;
635
+
636
+ for (const piece of contentPieces) {
637
+ node.syncManager.handleNewContent(piece, "import");
638
+ }
639
+ }