@pylonsync/sync 0.3.376 → 0.3.378

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.3.376",
6
+ "version": "0.3.378",
7
7
  "type": "module",
8
8
  "main": "./src/index.ts",
9
9
  "types": "./dist/index.d.ts",
@@ -591,4 +591,58 @@ describe("SyncEngine cookie auth", () => {
591
591
  restore();
592
592
  }
593
593
  });
594
+
595
+ // field.json() rows carry nested objects/arrays. rowsDiffer must
596
+ // recurse into them (drift at depth is real drift) while staying
597
+ // key-order-insensitive (same content, different key order, is NOT
598
+ // drift — an order-sensitive compare would re-upsert every json row
599
+ // on every reconcile pass).
600
+ test("nested json drift updates; key-order difference does not thrash", async () => {
601
+ const restoreFetch = installFetch(async (url) => {
602
+ if (url.includes("/api/entities/Doc/cursor")) {
603
+ return {
604
+ status: 200,
605
+ body: {
606
+ data: [
607
+ // drifted at depth vs the seeded row
608
+ { id: "doc_1", config: { theme: "dark", panes: [{ w: 2 }] } },
609
+ // identical content to the seed, different key order
610
+ { id: "doc_2", config: { b: 2, a: 1 } },
611
+ ],
612
+ next_cursor: null,
613
+ has_more: false,
614
+ },
615
+ };
616
+ }
617
+ return { status: 404, body: {} };
618
+ });
619
+
620
+ const engine = makeEngine();
621
+ seedStore(engine, "Doc", [
622
+ { id: "doc_1", config: { theme: "light", panes: [{ w: 2 }] } },
623
+ { id: "doc_2", config: { a: 1, b: 2 } },
624
+ ]);
625
+
626
+ let notifications = 0;
627
+ const unsub = engine.store.subscribe(() => {
628
+ notifications += 1;
629
+ });
630
+ try {
631
+ await engine.reconcile(["Doc"]);
632
+ } finally {
633
+ unsub();
634
+ restoreFetch();
635
+ }
636
+
637
+ const drifted = engine.store.get("Doc", "doc_1") as {
638
+ config: { theme: string };
639
+ } | null;
640
+ expect(drifted!.config.theme).toBe("dark");
641
+ const stable = engine.store.get("Doc", "doc_2") as {
642
+ config: Record<string, number>;
643
+ } | null;
644
+ expect(stable!.config).toEqual({ a: 1, b: 2 });
645
+ // Exactly one row changed → exactly one store notification.
646
+ expect(notifications).toBe(1);
647
+ });
594
648
  });