jazz-tools 0.20.1 → 0.20.3

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 (115) hide show
  1. package/.turbo/turbo-build.log +49 -49
  2. package/CHANGELOG.md +19 -6
  3. package/dist/{chunk-2OPP7KWV.js → chunk-Q5RNSSUM.js} +121 -22
  4. package/dist/chunk-Q5RNSSUM.js.map +1 -0
  5. package/dist/index.js +1 -1
  6. package/dist/inspector/{chunk-MCTB5ZJC.js → chunk-6JPVMI3V.js} +302 -182
  7. package/dist/inspector/chunk-6JPVMI3V.js.map +1 -0
  8. package/dist/inspector/{custom-element-5YWVZBWA.js → custom-element-WOQY2M4W.js} +1337 -206
  9. package/dist/inspector/custom-element-WOQY2M4W.js.map +1 -0
  10. package/dist/inspector/in-app.d.ts +1 -0
  11. package/dist/inspector/in-app.d.ts.map +1 -1
  12. package/dist/inspector/index.d.ts +1 -0
  13. package/dist/inspector/index.d.ts.map +1 -1
  14. package/dist/inspector/index.js +1044 -17
  15. package/dist/inspector/index.js.map +1 -1
  16. package/dist/inspector/pages/home.d.ts +4 -1
  17. package/dist/inspector/pages/home.d.ts.map +1 -1
  18. package/dist/inspector/pages/performance/PerformancePage.d.ts +7 -0
  19. package/dist/inspector/pages/performance/PerformancePage.d.ts.map +1 -0
  20. package/dist/inspector/pages/performance/SubscriptionDetailPanel.d.ts +8 -0
  21. package/dist/inspector/pages/performance/SubscriptionDetailPanel.d.ts.map +1 -0
  22. package/dist/inspector/pages/performance/SubscriptionRow.d.ts +11 -0
  23. package/dist/inspector/pages/performance/SubscriptionRow.d.ts.map +1 -0
  24. package/dist/inspector/pages/performance/Timeline.d.ts +12 -0
  25. package/dist/inspector/pages/performance/Timeline.d.ts.map +1 -0
  26. package/dist/inspector/pages/performance/helpers.d.ts +5 -0
  27. package/dist/inspector/pages/performance/helpers.d.ts.map +1 -0
  28. package/dist/inspector/pages/performance/index.d.ts +3 -0
  29. package/dist/inspector/pages/performance/index.d.ts.map +1 -0
  30. package/dist/inspector/pages/performance/types.d.ts +13 -0
  31. package/dist/inspector/pages/performance/types.d.ts.map +1 -0
  32. package/dist/inspector/pages/performance/usePerformanceEntries.d.ts +3 -0
  33. package/dist/inspector/pages/performance/usePerformanceEntries.d.ts.map +1 -0
  34. package/dist/inspector/register-custom-element.js +3 -1
  35. package/dist/inspector/register-custom-element.js.map +1 -1
  36. package/dist/inspector/standalone.js +1 -1
  37. package/dist/inspector/tests/pages/performance/PerformancePage.test.d.ts +2 -0
  38. package/dist/inspector/tests/pages/performance/PerformancePage.test.d.ts.map +1 -0
  39. package/dist/inspector/tests/pages/performance/SubscriptionDetailPanel.test.d.ts +2 -0
  40. package/dist/inspector/tests/pages/performance/SubscriptionDetailPanel.test.d.ts.map +1 -0
  41. package/dist/inspector/tests/pages/performance/SubscriptionRow.test.d.ts +2 -0
  42. package/dist/inspector/tests/pages/performance/SubscriptionRow.test.d.ts.map +1 -0
  43. package/dist/inspector/tests/pages/performance/Timeline.test.d.ts +2 -0
  44. package/dist/inspector/tests/pages/performance/Timeline.test.d.ts.map +1 -0
  45. package/dist/inspector/tests/pages/performance/helpers.test.d.ts +2 -0
  46. package/dist/inspector/tests/pages/performance/helpers.test.d.ts.map +1 -0
  47. package/dist/inspector/viewer/delete-local-data.d.ts.map +1 -1
  48. package/dist/inspector/viewer/header.d.ts +4 -2
  49. package/dist/inspector/viewer/header.d.ts.map +1 -1
  50. package/dist/inspector/viewer/page-stack.d.ts +3 -1
  51. package/dist/inspector/viewer/page-stack.d.ts.map +1 -1
  52. package/dist/react-core/hooks.d.ts +2 -2
  53. package/dist/react-core/hooks.d.ts.map +1 -1
  54. package/dist/react-core/index.js +50 -18
  55. package/dist/react-core/index.js.map +1 -1
  56. package/dist/react-core/subscription-provider.d.ts.map +1 -1
  57. package/dist/react-native-core/media/image.d.ts +1 -1
  58. package/dist/svelte/jazz.class.svelte.d.ts.map +1 -1
  59. package/dist/svelte/jazz.class.svelte.js +27 -22
  60. package/dist/testing.js +1 -1
  61. package/dist/tools/coValues/interfaces.d.ts.map +1 -1
  62. package/dist/tools/exports.d.ts +1 -1
  63. package/dist/tools/exports.d.ts.map +1 -1
  64. package/dist/tools/implementation/zodSchema/runtimeConverters/coValueSchemaTransformation.d.ts.map +1 -1
  65. package/dist/tools/subscribe/SubscriptionCache.d.ts +2 -2
  66. package/dist/tools/subscribe/SubscriptionCache.d.ts.map +1 -1
  67. package/dist/tools/subscribe/SubscriptionScope.d.ts +19 -12
  68. package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
  69. package/dist/tools/subscribe/errorReporting.d.ts +6 -0
  70. package/dist/tools/subscribe/errorReporting.d.ts.map +1 -1
  71. package/dist/tools/subscribe/index.d.ts +4 -4
  72. package/dist/tools/subscribe/index.d.ts.map +1 -1
  73. package/dist/tools/subscribe/types.d.ts +48 -3
  74. package/dist/tools/subscribe/types.d.ts.map +1 -1
  75. package/dist/tools/subscribe/utils.d.ts +1 -1
  76. package/dist/tools/subscribe/utils.d.ts.map +1 -1
  77. package/dist/tools/tests/SubscriptionScope.performance.test.d.ts +2 -0
  78. package/dist/tools/tests/SubscriptionScope.performance.test.d.ts.map +1 -0
  79. package/package.json +4 -4
  80. package/src/inspector/in-app.tsx +41 -3
  81. package/src/inspector/index.tsx +5 -1
  82. package/src/inspector/pages/home.tsx +26 -3
  83. package/src/inspector/pages/performance/PerformancePage.tsx +215 -0
  84. package/src/inspector/pages/performance/SubscriptionDetailPanel.tsx +182 -0
  85. package/src/inspector/pages/performance/SubscriptionRow.tsx +242 -0
  86. package/src/inspector/pages/performance/Timeline.tsx +513 -0
  87. package/src/inspector/pages/performance/helpers.ts +70 -0
  88. package/src/inspector/pages/performance/index.ts +2 -0
  89. package/src/inspector/pages/performance/types.ts +12 -0
  90. package/src/inspector/pages/performance/usePerformanceEntries.ts +53 -0
  91. package/src/inspector/register-custom-element.ts +3 -0
  92. package/src/inspector/tests/pages/performance/PerformancePage.test.tsx +83 -0
  93. package/src/inspector/tests/pages/performance/SubscriptionDetailPanel.test.tsx +68 -0
  94. package/src/inspector/tests/pages/performance/SubscriptionRow.test.tsx +93 -0
  95. package/src/inspector/tests/pages/performance/Timeline.test.tsx +57 -0
  96. package/src/inspector/tests/pages/performance/helpers.test.ts +91 -0
  97. package/src/inspector/viewer/delete-local-data.tsx +24 -5
  98. package/src/inspector/viewer/header.tsx +96 -17
  99. package/src/inspector/viewer/page-stack.tsx +22 -18
  100. package/src/react-core/hooks.ts +34 -4
  101. package/src/react-core/subscription-provider.tsx +17 -8
  102. package/src/svelte/jazz.class.svelte.ts +51 -33
  103. package/src/tools/coValues/interfaces.ts +3 -0
  104. package/src/tools/exports.ts +1 -0
  105. package/src/tools/implementation/zodSchema/runtimeConverters/coValueSchemaTransformation.ts +13 -0
  106. package/src/tools/subscribe/SubscriptionCache.ts +6 -4
  107. package/src/tools/subscribe/SubscriptionScope.ts +141 -23
  108. package/src/tools/subscribe/errorReporting.ts +1 -1
  109. package/src/tools/subscribe/index.ts +1 -1
  110. package/src/tools/subscribe/types.ts +62 -9
  111. package/src/tools/subscribe/utils.ts +2 -2
  112. package/src/tools/tests/SubscriptionScope.performance.test.ts +149 -0
  113. package/dist/chunk-2OPP7KWV.js.map +0 -1
  114. package/dist/inspector/chunk-MCTB5ZJC.js.map +0 -1
  115. package/dist/inspector/custom-element-5YWVZBWA.js.map +0 -1
@@ -1,10 +1,4 @@
1
- import type {
2
- Account,
3
- CoValue,
4
- Group,
5
- RefsToResolve,
6
- Resolved,
7
- } from "../internal.js";
1
+ import type { Account, CoValue, Group, Resolved } from "../internal.js";
8
2
  import type { JazzError } from "./JazzError.js";
9
3
 
10
4
  export const CoValueLoadingState = {
@@ -42,10 +36,10 @@ export type NotLoadedCoValueState =
42
36
  | typeof CoValueLoadingState.LOADING
43
37
  | CoValueErrorState;
44
38
 
45
- export type SubscriptionValue<D extends CoValue, R extends RefsToResolve<D>> =
39
+ export type SubscriptionValue<D> =
46
40
  | {
47
41
  type: typeof CoValueLoadingState.LOADED;
48
- value: Resolved<D, R>;
42
+ value: D;
49
43
  id: string;
50
44
  }
51
45
  | JazzError;
@@ -55,3 +49,62 @@ export type SubscriptionValueLoading = {
55
49
  };
56
50
 
57
51
  export type BranchDefinition = { name: string; owner?: Group | Account };
52
+
53
+ /**
54
+ * Detail structure for subscription performance marks and measures.
55
+ * Used by SubscriptionScope.trackLoadingPerformance() to emit performance data.
56
+ */
57
+ export interface SubscriptionPerformanceDetail {
58
+ /** Type of performance entry */
59
+ type: "jazz-subscription";
60
+ /** Unique identifier for this subscription instance */
61
+ uuid: string;
62
+ /** CoValue ID (e.g., "co_z1234...") */
63
+ id: string;
64
+ /** Source identifier (hook name or API) */
65
+ source: string;
66
+ /** The resolve query object */
67
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
68
+ resolve: any;
69
+ /** Current status of the subscription */
70
+ status: "pending" | "loaded" | "error";
71
+ /** When the subscription started loading (DOMHighResTimeStamp) */
72
+ startTime: number;
73
+ /** When loading completed (if completed) */
74
+ endTime?: number;
75
+ /** Total load time in ms (if completed) */
76
+ duration?: number;
77
+ /** Error type if status is "error" */
78
+ errorType?: "unavailable" | "unauthorized" | "deleted";
79
+ /** Stack trace captured at subscription creation time */
80
+ callerStack?: string;
81
+ devtools?: ExtensionTrackEntryPayload | ExtensionMarkerPayload;
82
+ }
83
+
84
+ type DevToolsColor =
85
+ | "primary"
86
+ | "primary-light"
87
+ | "primary-dark"
88
+ | "secondary"
89
+ | "secondary-light"
90
+ | "secondary-dark"
91
+ | "tertiary"
92
+ | "tertiary-light"
93
+ | "tertiary-dark"
94
+ | "error";
95
+
96
+ interface ExtensionTrackEntryPayload {
97
+ dataType?: "track-entry"; // Defaults to "track-entry"
98
+ color?: DevToolsColor; // Defaults to "primary"
99
+ track: string; // Required: Name of the custom track
100
+ trackGroup?: string; // Optional: Group for organizing tracks
101
+ properties?: [string, string][]; // Key-value pairs for detailed view
102
+ tooltipText?: string; // Short description for tooltip
103
+ }
104
+
105
+ interface ExtensionMarkerPayload {
106
+ dataType: "marker"; // Required: Identifies as a marker
107
+ color?: DevToolsColor; // Defaults to "primary"
108
+ properties?: [string, string][]; // Key-value pairs for detailed view
109
+ tooltipText?: string; // Short description for tooltip
110
+ }
@@ -24,7 +24,7 @@ export function myRoleForRawValue(raw: RawCoValue): Role | undefined {
24
24
  }
25
25
 
26
26
  export function createCoValue<D extends CoValue>(
27
- ref: RefEncoded<D>,
27
+ ref: RefEncoded<CoValue>,
28
28
  raw: RawCoValue,
29
29
  subscriptionScope: SubscriptionScope<D>,
30
30
  ) {
@@ -39,7 +39,7 @@ export function createCoValue<D extends CoValue>(
39
39
 
40
40
  return {
41
41
  type: CoValueLoadingState.LOADED,
42
- value: freshValueInstance,
42
+ value: freshValueInstance as unknown as D,
43
43
  id: subscriptionScope.id,
44
44
  };
45
45
  }
@@ -0,0 +1,149 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
2
+ import { SubscriptionScope } from "../subscribe/SubscriptionScope.js";
3
+ import { setupJazzTestSync } from "../testing.js";
4
+ import { setupAccount } from "./utils.js";
5
+ import { z } from "../index.js";
6
+ import { co } from "../internal.js";
7
+ import { CoID, RawCoValue, cojsonInternals } from "cojson";
8
+
9
+ describe("SubscriptionScope performance profiling", () => {
10
+ beforeEach(async () => {
11
+ await setupJazzTestSync();
12
+ SubscriptionScope.setProfilingEnabled(true);
13
+ performance.clearMarks();
14
+ performance.clearMeasures();
15
+ cojsonInternals.setCoValueLoadingRetryDelay(100);
16
+ });
17
+
18
+ afterEach(() => {
19
+ SubscriptionScope.setProfilingEnabled(false);
20
+ });
21
+
22
+ it("emits performance entries on successful load", async () => {
23
+ const { me, meOnSecondPeer } = await setupAccount();
24
+
25
+ const TestMap = co.map({ name: z.string() });
26
+ const value = TestMap.create({ name: "test" }, { owner: me });
27
+
28
+ const loaded = await TestMap.load(value.$jazz.id, {
29
+ loadAs: meOnSecondPeer,
30
+ });
31
+
32
+ expect(loaded).toBeDefined();
33
+
34
+ const measures = performance.getEntriesByType(
35
+ "measure",
36
+ ) as PerformanceMeasure[];
37
+ const measure = measures.find(
38
+ (m) =>
39
+ (m as PerformanceMeasure & { detail?: { id?: string } }).detail?.id ===
40
+ value.$jazz.id,
41
+ );
42
+
43
+ expect(measure).toBeDefined();
44
+ const detail = (
45
+ measure as PerformanceMeasure & { detail: Record<string, unknown> }
46
+ ).detail;
47
+ expect(detail.type).toBe("jazz-subscription");
48
+ expect(detail.status).toBe("loaded");
49
+ expect(detail.uuid).toBeDefined();
50
+ expect(detail.source).toBeDefined();
51
+ expect(detail.resolve).toBeDefined();
52
+ expect(measure!.duration).toBeGreaterThan(0);
53
+ });
54
+
55
+ it("does not emit performance entries when profiling is disabled", async () => {
56
+ SubscriptionScope.setProfilingEnabled(false);
57
+
58
+ const { me, meOnSecondPeer } = await setupAccount();
59
+
60
+ const TestMap = co.map({ name: z.string() });
61
+ const value = TestMap.create({ name: "test" }, { owner: me });
62
+
63
+ const loaded = await TestMap.load(value.$jazz.id, {
64
+ loadAs: meOnSecondPeer,
65
+ });
66
+
67
+ expect(loaded).toBeDefined();
68
+
69
+ // Verify no jazz-subscription entries were created
70
+ const measures = performance.getEntriesByType(
71
+ "measure",
72
+ ) as PerformanceMeasure[];
73
+ const jazzMeasures = measures.filter(
74
+ (m) =>
75
+ (m as PerformanceMeasure & { detail?: { type?: string } }).detail
76
+ ?.type === "jazz-subscription",
77
+ );
78
+ expect(jazzMeasures.length).toBe(0);
79
+
80
+ const marks = performance.getEntriesByType("mark") as PerformanceMark[];
81
+ const jazzMarks = marks.filter(
82
+ (m) =>
83
+ (m as PerformanceMark & { detail?: { type?: string } }).detail?.type ===
84
+ "jazz-subscription",
85
+ );
86
+ expect(jazzMarks.length).toBe(0);
87
+ });
88
+
89
+ it("emits performance entries with error status on unavailable", async () => {
90
+ const { meOnSecondPeer } = await setupAccount();
91
+
92
+ const TestMap = co.map({ name: z.string() });
93
+ const fakeId = "co_zFAKEIDTHATDOESNOTEXIST123" as CoID<RawCoValue>;
94
+
95
+ const loaded = await TestMap.load(fakeId, { loadAs: meOnSecondPeer });
96
+
97
+ expect(loaded.$isLoaded).toBe(false);
98
+
99
+ const measures = performance.getEntriesByType(
100
+ "measure",
101
+ ) as PerformanceMeasure[];
102
+ const measure = measures.find(
103
+ (m) =>
104
+ (m as PerformanceMeasure & { detail?: { id?: string } }).detail?.id ===
105
+ fakeId,
106
+ );
107
+
108
+ expect(measure).toBeDefined();
109
+ const detail = (
110
+ measure as PerformanceMeasure & { detail: Record<string, unknown> }
111
+ ).detail;
112
+ expect(detail.status).toBe("error");
113
+ expect(detail.errorType).toBe("unavailable");
114
+ });
115
+
116
+ it("emits start and end marks with correct detail", async () => {
117
+ const { me, meOnSecondPeer } = await setupAccount();
118
+
119
+ const TestMap = co.map({ name: z.string() });
120
+ const value = TestMap.create({ name: "test" }, { owner: me });
121
+
122
+ await TestMap.load(value.$jazz.id, { loadAs: meOnSecondPeer });
123
+
124
+ const marks = performance.getEntriesByType("mark") as PerformanceMark[];
125
+ const startMark = marks.find(
126
+ (m) =>
127
+ m.name.startsWith("jazz.subscription.start:") &&
128
+ (m as PerformanceMark & { detail?: { id?: string } }).detail?.id ===
129
+ value.$jazz.id,
130
+ );
131
+ const endMark = marks.find(
132
+ (m) =>
133
+ m.name.startsWith("jazz.subscription.end:") &&
134
+ (m as PerformanceMark & { detail?: { id?: string } }).detail?.id ===
135
+ value.$jazz.id,
136
+ );
137
+
138
+ expect(startMark).toBeDefined();
139
+ expect(endMark).toBeDefined();
140
+ expect(
141
+ (startMark as PerformanceMark & { detail: { status: string } }).detail
142
+ .status,
143
+ ).toBe("pending");
144
+ expect(
145
+ (endMark as PerformanceMark & { detail: { status: string } }).detail
146
+ .status,
147
+ ).toBe("loaded");
148
+ });
149
+ });