@rocicorp/zero 0.22.2025080201 → 0.23.2025081200

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 (114) hide show
  1. package/out/analyze-query/src/bin-analyze.js +5 -8
  2. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  3. package/out/{chunk-LENWM5WE.js → chunk-6TQKR5IL.js} +323 -203
  4. package/out/chunk-6TQKR5IL.js.map +7 -0
  5. package/out/chunk-MKB4RXL3.js +15 -0
  6. package/out/chunk-MKB4RXL3.js.map +7 -0
  7. package/out/chunk-SGW2EIVJ.js +192 -0
  8. package/out/chunk-SGW2EIVJ.js.map +7 -0
  9. package/out/{chunk-QVKOYV54.js → chunk-YTS56A64.js} +200 -134
  10. package/out/chunk-YTS56A64.js.map +7 -0
  11. package/out/{chunk-PDLFYV2P.js → chunk-ZJ4VVIKN.js} +6 -4
  12. package/out/chunk-ZJ4VVIKN.js.map +7 -0
  13. package/out/expo.js +356 -0
  14. package/out/expo.js.map +7 -0
  15. package/out/{inspector-AF3UI76B.js → inspector-RB55U26N.js} +86 -26
  16. package/out/inspector-RB55U26N.js.map +7 -0
  17. package/out/{inspector-ENPS6L3H.js → inspector-YIRP3TTL.js} +1 -1
  18. package/out/{inspector-ENPS6L3H.js.map → inspector-YIRP3TTL.js.map} +1 -1
  19. package/out/react.js +7 -4
  20. package/out/react.js.map +2 -2
  21. package/out/replicache/src/kv/sqlite-store.d.ts +117 -0
  22. package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -0
  23. package/out/shared/src/centroid.d.ts +10 -0
  24. package/out/shared/src/centroid.d.ts.map +1 -0
  25. package/out/shared/src/dotenv.js +5 -0
  26. package/out/shared/src/dotenv.js.map +1 -1
  27. package/out/shared/src/tdigest.d.ts +42 -0
  28. package/out/shared/src/tdigest.d.ts.map +1 -0
  29. package/out/solid.js +13 -9
  30. package/out/solid.js.map +2 -2
  31. package/out/zero/package.json +7 -4
  32. package/out/zero/src/expo.d.ts +2 -0
  33. package/out/zero/src/expo.d.ts.map +1 -0
  34. package/out/zero/src/zero-cache-dev.js.map +1 -1
  35. package/out/zero-cache/src/auth/write-authorizer.d.ts +1 -0
  36. package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
  37. package/out/zero-cache/src/auth/write-authorizer.js +10 -5
  38. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  39. package/out/zero-cache/src/config/zero-config.d.ts +0 -10
  40. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  41. package/out/zero-cache/src/config/zero-config.js +0 -5
  42. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  43. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  44. package/out/zero-cache/src/services/mutagen/mutagen.js +1 -0
  45. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  46. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  47. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +2 -1
  48. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  49. package/out/zero-cache/src/types/pg.d.ts +9 -0
  50. package/out/zero-cache/src/types/pg.d.ts.map +1 -1
  51. package/out/zero-cache/src/types/pg.js +78 -1
  52. package/out/zero-cache/src/types/pg.js.map +1 -1
  53. package/out/zero-client/src/client/context.d.ts +11 -11
  54. package/out/zero-client/src/client/context.d.ts.map +1 -1
  55. package/out/zero-client/src/client/custom.d.ts +6 -6
  56. package/out/zero-client/src/client/custom.d.ts.map +1 -1
  57. package/out/zero-client/src/client/inspector/inspector.d.ts +10 -1
  58. package/out/zero-client/src/client/inspector/inspector.d.ts.map +1 -1
  59. package/out/zero-client/src/client/inspector/types.d.ts +8 -0
  60. package/out/zero-client/src/client/inspector/types.d.ts.map +1 -1
  61. package/out/zero-client/src/client/measure-push-operator.d.ts +17 -0
  62. package/out/zero-client/src/client/measure-push-operator.d.ts.map +1 -0
  63. package/out/zero-client/src/client/options.d.ts +2 -2
  64. package/out/zero-client/src/client/options.d.ts.map +1 -1
  65. package/out/zero-client/src/client/query-manager.d.ts +18 -5
  66. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  67. package/out/zero-client/src/client/zero.d.ts +4 -4
  68. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  69. package/out/zero-client/src/mod.d.ts +1 -1
  70. package/out/zero-client/src/mod.d.ts.map +1 -1
  71. package/out/zero-expo/src/mod.d.ts +2 -0
  72. package/out/zero-expo/src/mod.d.ts.map +1 -0
  73. package/out/zero-expo/src/store.d.ts +4 -0
  74. package/out/zero-expo/src/store.d.ts.map +1 -0
  75. package/out/zero-react/src/components/inspector.d.ts +1 -1
  76. package/out/zero-react/src/components/inspector.d.ts.map +1 -1
  77. package/out/zero-react/src/components/zero-inspector.d.ts +1 -1
  78. package/out/zero-react/src/components/zero-inspector.d.ts.map +1 -1
  79. package/out/zero-react/src/zero-provider.d.ts +4 -4
  80. package/out/zero-react/src/zero-provider.d.ts.map +1 -1
  81. package/out/zero-schema/src/permissions.d.ts +15 -0
  82. package/out/zero-schema/src/permissions.d.ts.map +1 -1
  83. package/out/zero-schema/src/table-schema.d.ts +1 -8
  84. package/out/zero-schema/src/table-schema.d.ts.map +1 -1
  85. package/out/zero-schema/src/table-schema.js.map +1 -1
  86. package/out/zero-solid/src/use-zero.d.ts +4 -4
  87. package/out/zero-solid/src/use-zero.d.ts.map +1 -1
  88. package/out/zero.js +5 -3
  89. package/out/zql/src/builder/builder.d.ts +3 -2
  90. package/out/zql/src/builder/builder.d.ts.map +1 -1
  91. package/out/zql/src/builder/builder.js +9 -8
  92. package/out/zql/src/builder/builder.js.map +1 -1
  93. package/out/zql/src/ivm/operator.d.ts +1 -1
  94. package/out/zql/src/ivm/operator.d.ts.map +1 -1
  95. package/out/zql/src/ivm/operator.js +0 -1
  96. package/out/zql/src/ivm/operator.js.map +1 -1
  97. package/out/zql/src/query/metrics-delegate.d.ts +10 -0
  98. package/out/zql/src/query/metrics-delegate.d.ts.map +1 -0
  99. package/out/zql/src/query/metrics-delegate.js +2 -0
  100. package/out/zql/src/query/metrics-delegate.js.map +1 -0
  101. package/out/zql/src/query/query-delegate.d.ts +7 -2
  102. package/out/zql/src/query/query-delegate.d.ts.map +1 -1
  103. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  104. package/out/zql/src/query/query-impl.js +17 -14
  105. package/out/zql/src/query/query-impl.js.map +1 -1
  106. package/out/zqlite/src/query-delegate.d.ts +7 -6
  107. package/out/zqlite/src/query-delegate.d.ts.map +1 -1
  108. package/out/zqlite/src/query-delegate.js +5 -2
  109. package/out/zqlite/src/query-delegate.js.map +1 -1
  110. package/package.json +7 -4
  111. package/out/chunk-LENWM5WE.js.map +0 -7
  112. package/out/chunk-PDLFYV2P.js.map +0 -7
  113. package/out/chunk-QVKOYV54.js.map +0 -7
  114. package/out/inspector-AF3UI76B.js.map +0 -7
@@ -1,3 +1,8 @@
1
+ import {
2
+ promiseFalse,
3
+ promiseTrue,
4
+ promiseVoid
5
+ } from "./chunk-MKB4RXL3.js";
1
6
  import {
2
7
  BTreeRead,
3
8
  Chunk,
@@ -10,11 +15,10 @@ import {
10
15
  GOT_QUERIES_KEY_PREFIX,
11
16
  Latest,
12
17
  MUTATIONS_KEY_PREFIX,
18
+ TDigest,
13
19
  V6,
14
20
  V7,
15
21
  addDiffsForIndexes,
16
- assert,
17
- assertArray,
18
22
  assertClientV6,
19
23
  assertCookie,
20
24
  assertHasClientState,
@@ -22,14 +26,10 @@ import {
22
26
  assertJSONObject,
23
27
  assertJSONValue,
24
28
  assertLocalMetaDD31,
25
- assertNotNull,
26
- assertNumber,
27
- assertObject,
28
29
  assertOrderingIncludesPK,
29
30
  assertRefs,
30
31
  assertSnapshotCommitDD31,
31
32
  assertSnapshotMetaDD31,
32
- assertString,
33
33
  astSchema,
34
34
  asyncIterableToArray,
35
35
  baseSnapshotFromCommit,
@@ -51,8 +51,6 @@ import {
51
51
  createPredicate,
52
52
  decodeIndexKey,
53
53
  deepEqual,
54
- deepFreeze,
55
- deepFreezeAllowUndefined,
56
54
  desiredQueriesPrefixForClient,
57
55
  diff,
58
56
  diff2,
@@ -70,13 +68,11 @@ import {
70
68
  getSizeOfValue,
71
69
  h64,
72
70
  hasClientState,
73
- hasOwn,
74
71
  hashOfAST,
75
72
  hashOfNameAndArgs,
76
73
  initClientV6,
77
74
  inspectDownMessageSchema,
78
75
  isLocalMetaDD31,
79
- isProd,
80
76
  joinIterables,
81
77
  jsonObjectSchema,
82
78
  jsonSchema,
@@ -115,12 +111,12 @@ import {
115
111
  sourceNameFromKey,
116
112
  stringCompare,
117
113
  test,
114
+ throwOutput,
118
115
  toDesiredQueriesKey,
119
116
  toGotQueriesKey,
120
117
  toMutationResponseKey,
121
118
  toPrimaryKeyString,
122
119
  transformFilters,
123
- unreachable,
124
120
  using,
125
121
  valita_exports,
126
122
  valuesEqual,
@@ -128,7 +124,20 @@ import {
128
124
  withWrite,
129
125
  withWriteNoImplicitCommit,
130
126
  wrapIterable
131
- } from "./chunk-LENWM5WE.js";
127
+ } from "./chunk-6TQKR5IL.js";
128
+ import {
129
+ assert,
130
+ assertArray,
131
+ assertNotNull,
132
+ assertNumber,
133
+ assertObject,
134
+ assertString,
135
+ deepFreeze,
136
+ deepFreezeAllowUndefined,
137
+ hasOwn,
138
+ isProd,
139
+ unreachable
140
+ } from "./chunk-SGW2EIVJ.js";
132
141
  import {
133
142
  __export
134
143
  } from "./chunk-424PT5DM.js";
@@ -316,14 +325,6 @@ function mustGetBrowserGlobal(name) {
316
325
  return r;
317
326
  }
318
327
 
319
- // ../shared/src/resolved-promises.ts
320
- var promiseTrue = Promise.resolve(true);
321
- var promiseFalse = Promise.resolve(false);
322
- var promiseUndefined = Promise.resolve(void 0);
323
- var promiseVoid = Promise.resolve();
324
- var promiseNever = new Promise(() => {
325
- });
326
-
327
328
  // ../replicache/src/kv/write-impl-base.ts
328
329
  var deleteSentinel = Symbol();
329
330
  var WriteImplBase = class {
@@ -826,7 +827,7 @@ import { resolver as resolver4 } from "@rocicorp/resolver";
826
827
  // ../shared/src/sleep.ts
827
828
  import { resolver as resolver3 } from "@rocicorp/resolver";
828
829
  var promiseVoid2 = Promise.resolve();
829
- var promiseNever2 = new Promise(() => void 0);
830
+ var promiseNever = new Promise(() => void 0);
830
831
  function sleep(ms, signal) {
831
832
  const newAbortError = () => new AbortError("Aborted");
832
833
  if (signal?.aborted) {
@@ -852,7 +853,7 @@ function sleep(ms, signal) {
852
853
  }
853
854
  function sleepWithAbort(ms, signal) {
854
855
  if (ms === 0) {
855
- return [promiseVoid2, promiseNever2];
856
+ return [promiseVoid2, promiseNever];
856
857
  }
857
858
  const { promise: abortedPromise, resolve: abortedResolve } = resolver3();
858
859
  const sleepPromise = new Promise((resolve) => {
@@ -5849,6 +5850,38 @@ var SchemaVersionNotSupported2 = "SchemaVersionNotSupported";
5849
5850
  import "@rocicorp/logger";
5850
5851
  import { resolver as resolver9 } from "@rocicorp/resolver";
5851
5852
 
5853
+ // ../shared/src/subscribable.ts
5854
+ var Subscribable = class {
5855
+ _listeners = /* @__PURE__ */ new Set();
5856
+ /**
5857
+ * Subscribe to the subscribable.
5858
+ *
5859
+ * @param listener - The listener to subscribe to.
5860
+ * @returns A function to unsubscribe from the subscribable.
5861
+ */
5862
+ subscribe = (listener) => {
5863
+ this._listeners.add(listener);
5864
+ return () => {
5865
+ this._listeners.delete(listener);
5866
+ };
5867
+ };
5868
+ /**
5869
+ * Notify all listeners.
5870
+ *
5871
+ * @param update - The update to notify listeners with.
5872
+ */
5873
+ notify = (update) => {
5874
+ this._listeners.forEach((listener) => listener(update));
5875
+ };
5876
+ hasListeners = () => this._listeners.size > 0;
5877
+ /**
5878
+ * Unsubscribe all listeners.
5879
+ */
5880
+ cleanup = () => {
5881
+ this._listeners.clear();
5882
+ };
5883
+ };
5884
+
5852
5885
  // ../zero-protocol/src/delete-clients.ts
5853
5886
  var deleteClientsBodySchema = valita_exports.union(
5854
5887
  readonlyObject({
@@ -7812,6 +7845,44 @@ function applyDiffs(diffs, branch) {
7812
7845
  }
7813
7846
  }
7814
7847
 
7848
+ // ../zero-client/src/client/measure-push-operator.ts
7849
+ var MeasurePushOperator = class {
7850
+ #input;
7851
+ #queryID;
7852
+ #metricsDelegate;
7853
+ #output = throwOutput;
7854
+ constructor(input, queryID, metricsDelegate) {
7855
+ this.#input = input;
7856
+ this.#queryID = queryID;
7857
+ this.#metricsDelegate = metricsDelegate;
7858
+ input.setOutput(this);
7859
+ }
7860
+ setOutput(output) {
7861
+ this.#output = output;
7862
+ }
7863
+ fetch(req) {
7864
+ return this.#input.fetch(req);
7865
+ }
7866
+ cleanup(req) {
7867
+ return this.#input.cleanup(req);
7868
+ }
7869
+ getSchema() {
7870
+ return this.#input.getSchema();
7871
+ }
7872
+ destroy() {
7873
+ this.#input.destroy();
7874
+ }
7875
+ push(change) {
7876
+ const startTime = performance.now();
7877
+ this.#output.push(change);
7878
+ this.#metricsDelegate.addMetric(
7879
+ "query-update-client",
7880
+ performance.now() - startTime,
7881
+ this.#queryID
7882
+ );
7883
+ }
7884
+ };
7885
+
7815
7886
  // ../zero-client/src/client/context.ts
7816
7887
  var ZeroContext = class {
7817
7888
  // It is a bummer to have to maintain separate MemorySources here and copy the
@@ -7819,14 +7890,13 @@ var ZeroContext = class {
7819
7890
  // pipelines *synchronously* and the core Replicache infra is all async. So
7820
7891
  // that needs to be fixed.
7821
7892
  #mainSources;
7822
- #addQuery;
7823
- #addCustomQuery;
7824
- #updateQuery;
7825
- #updateCustomQuery;
7826
- #flushQueryChanges;
7893
+ addServerQuery;
7894
+ addCustomQuery;
7895
+ updateServerQuery;
7896
+ updateCustomQuery;
7897
+ flushQueryChanges;
7827
7898
  #batchViewUpdates;
7828
7899
  #commitListeners = /* @__PURE__ */ new Set();
7829
- #slowMaterializeThreshold;
7830
7900
  #lc;
7831
7901
  assertValidRunOptions;
7832
7902
  /**
@@ -7834,58 +7904,22 @@ var ZeroContext = class {
7834
7904
  * "complete" once the server has sent back the query result.
7835
7905
  */
7836
7906
  defaultQueryComplete = false;
7837
- constructor(lc, mainSources, addQuery, addCustomQuery, updateQuery, updateCustomQuery, flushQueryChanges, batchViewUpdates, slowMaterializeThreshold, assertValidRunOptions3) {
7907
+ addMetric;
7908
+ constructor(lc, mainSources, addQuery, addCustomQuery, updateQuery, updateCustomQuery, flushQueryChanges, batchViewUpdates, addMetric, assertValidRunOptions3) {
7838
7909
  this.#mainSources = mainSources;
7839
- this.#addQuery = addQuery;
7840
- this.#updateQuery = updateQuery;
7841
- this.#updateCustomQuery = updateCustomQuery;
7910
+ this.addServerQuery = addQuery;
7911
+ this.updateServerQuery = updateQuery;
7912
+ this.updateCustomQuery = updateCustomQuery;
7842
7913
  this.#batchViewUpdates = batchViewUpdates;
7843
7914
  this.#lc = lc;
7844
- this.#slowMaterializeThreshold = slowMaterializeThreshold;
7845
7915
  this.assertValidRunOptions = assertValidRunOptions3;
7846
- this.#addCustomQuery = addCustomQuery;
7847
- this.#flushQueryChanges = flushQueryChanges;
7916
+ this.addCustomQuery = addCustomQuery;
7917
+ this.flushQueryChanges = flushQueryChanges;
7918
+ this.addMetric = addMetric;
7848
7919
  }
7849
7920
  getSource(name) {
7850
7921
  return this.#mainSources.getSource(name);
7851
7922
  }
7852
- addCustomQuery(customQueryID, ttl, gotCallback) {
7853
- return this.#addCustomQuery(
7854
- customQueryID.name,
7855
- customQueryID.args,
7856
- ttl,
7857
- gotCallback
7858
- );
7859
- }
7860
- addServerQuery(ast, ttl, gotCallback) {
7861
- return this.#addQuery(ast, ttl, gotCallback);
7862
- }
7863
- updateServerQuery(ast, ttl) {
7864
- this.#updateQuery(ast, ttl);
7865
- }
7866
- updateCustomQuery(customQueryID, ttl) {
7867
- this.#updateCustomQuery(customQueryID.name, customQueryID.args, ttl);
7868
- }
7869
- flushQueryChanges() {
7870
- this.#flushQueryChanges();
7871
- }
7872
- onQueryMaterialized(hash, ast, duration) {
7873
- if (this.#slowMaterializeThreshold !== void 0 && duration > this.#slowMaterializeThreshold) {
7874
- this.#lc.warn?.(
7875
- "Slow query materialization (including server/network)",
7876
- hash,
7877
- ast,
7878
- duration
7879
- );
7880
- } else {
7881
- this.#lc.debug?.(
7882
- "Materialized query (including server/network)",
7883
- hash,
7884
- ast,
7885
- duration
7886
- );
7887
- }
7888
- }
7889
7923
  mapAst(ast) {
7890
7924
  return ast;
7891
7925
  }
@@ -7898,6 +7932,9 @@ var ZeroContext = class {
7898
7932
  decorateFilterInput(input) {
7899
7933
  return input;
7900
7934
  }
7935
+ decorateSourceInput(input, queryID) {
7936
+ return new MeasurePushOperator(input, queryID, this);
7937
+ }
7901
7938
  onTransactionCommit(cb) {
7902
7939
  this.#commitListeners.add(cb);
7903
7940
  return () => {
@@ -8167,7 +8204,7 @@ var emptyObject = Object.freeze({});
8167
8204
 
8168
8205
  // ../zero-client/src/client/custom.ts
8169
8206
  var TransactionImpl = class {
8170
- constructor(lc, repTx, schema, slowMaterializeThreshold) {
8207
+ constructor(lc, repTx, schema) {
8171
8208
  const castedRepTx = repTx;
8172
8209
  must(repTx.reason === "initial" || repTx.reason === "rebase");
8173
8210
  this.clientID = repTx.clientID;
@@ -8185,8 +8222,7 @@ var TransactionImpl = class {
8185
8222
  this.query = makeSchemaQuery(
8186
8223
  lc,
8187
8224
  schema,
8188
- txData.ivmSources,
8189
- slowMaterializeThreshold
8225
+ txData.ivmSources
8190
8226
  );
8191
8227
  this.token = txData.token;
8192
8228
  }
@@ -8198,9 +8234,9 @@ var TransactionImpl = class {
8198
8234
  query;
8199
8235
  token;
8200
8236
  };
8201
- function makeReplicacheMutator(lc, mutator, schema, slowMaterializeThreshold) {
8237
+ function makeReplicacheMutator(lc, mutator, schema) {
8202
8238
  return async (repTx, args) => {
8203
- const tx = new TransactionImpl(lc, repTx, schema, slowMaterializeThreshold);
8239
+ const tx = new TransactionImpl(lc, repTx, schema);
8204
8240
  await mutator(tx, args);
8205
8241
  };
8206
8242
  }
@@ -8224,7 +8260,7 @@ function assertValidRunOptions(options) {
8224
8260
  "Cannot wait for complete results in custom mutations"
8225
8261
  );
8226
8262
  }
8227
- function makeSchemaQuery(lc, schema, ivmBranch, slowMaterializeThreshold) {
8263
+ function makeSchemaQuery(lc, schema, ivmBranch) {
8228
8264
  const context = new ZeroContext(
8229
8265
  lc,
8230
8266
  ivmBranch,
@@ -8234,7 +8270,7 @@ function makeSchemaQuery(lc, schema, ivmBranch, slowMaterializeThreshold) {
8234
8270
  emptyFunction,
8235
8271
  emptyFunction,
8236
8272
  (applyViewUpdates) => applyViewUpdates(),
8237
- slowMaterializeThreshold,
8273
+ emptyFunction,
8238
8274
  assertValidRunOptions
8239
8275
  );
8240
8276
  return new Proxy(
@@ -8580,7 +8616,7 @@ function makeMessage(message, context, logLevel) {
8580
8616
  }
8581
8617
 
8582
8618
  // ../zero-client/src/client/version.ts
8583
- var version2 = "0.22.2025080201";
8619
+ var version2 = "0.23.2025081200";
8584
8620
 
8585
8621
  // ../zero-client/src/client/log-options.ts
8586
8622
  var LevelFilterLogSink = class {
@@ -9149,7 +9185,10 @@ var QueryManager = class {
9149
9185
  #pendingRemovals = [];
9150
9186
  #batchTimer;
9151
9187
  #lc;
9152
- constructor(lc, mutationTracker, clientID, tables, send2, experimentalWatch, recentQueriesMaxSize, queryChangeThrottleMs) {
9188
+ #metrics = newMetrics();
9189
+ #queryMetrics = /* @__PURE__ */ new Map();
9190
+ #slowMaterializeThreshold;
9191
+ constructor(lc, mutationTracker, clientID, tables, send2, experimentalWatch, recentQueriesMaxSize, queryChangeThrottleMs, slowMaterializeThreshold) {
9153
9192
  this.#lc = lc.withContext("QueryManager");
9154
9193
  this.#clientID = clientID;
9155
9194
  this.#clientToServer = clientToServer(tables);
@@ -9157,6 +9196,7 @@ var QueryManager = class {
9157
9196
  this.#send = send2;
9158
9197
  this.#mutationTracker = mutationTracker;
9159
9198
  this.#queryChangeThrottleMs = queryChangeThrottleMs;
9199
+ this.#slowMaterializeThreshold = slowMaterializeThreshold;
9160
9200
  this.#mutationTracker.onAllMutationsApplied(() => {
9161
9201
  if (this.#pendingRemovals.length === 0) {
9162
9202
  return;
@@ -9252,7 +9292,7 @@ var QueryManager = class {
9252
9292
  }
9253
9293
  return patch;
9254
9294
  }
9255
- addCustom(name, args, ttl, gotCallback) {
9295
+ addCustom({ name, args }, ttl, gotCallback) {
9256
9296
  const queryId = hashOfNameAndArgs(name, args);
9257
9297
  return this.#add(
9258
9298
  queryId,
@@ -9332,7 +9372,7 @@ var QueryManager = class {
9332
9372
  this.#remove(entry, queryId, gotCallback);
9333
9373
  };
9334
9374
  }
9335
- updateCustom(name, args, ttl) {
9375
+ updateCustom({ name, args }, ttl) {
9336
9376
  const hash = hashOfNameAndArgs(name, args);
9337
9377
  const entry = must(this.#queries.get(hash));
9338
9378
  this.#updateEntry(entry, hash, ttl);
@@ -9393,15 +9433,61 @@ var QueryManager = class {
9393
9433
  if (entry.count === 0) {
9394
9434
  this.#recentQueries.add(astHash);
9395
9435
  if (this.#recentQueries.size > this.#recentQueriesMaxSize) {
9396
- const lruAstHash = this.#recentQueries.values().next().value;
9397
- assert(lruAstHash);
9398
- this.#queries.delete(lruAstHash);
9399
- this.#recentQueries.delete(lruAstHash);
9400
- this.#queueQueryChange({ op: "del", hash: lruAstHash });
9436
+ const lruQueryID = this.#recentQueries.values().next().value;
9437
+ assert(lruQueryID);
9438
+ this.#queries.delete(lruQueryID);
9439
+ this.#recentQueries.delete(lruQueryID);
9440
+ this.#queryMetrics.delete(lruQueryID);
9441
+ this.#queueQueryChange({ op: "del", hash: lruQueryID });
9442
+ }
9443
+ }
9444
+ }
9445
+ /**
9446
+ * Gets the aggregated metrics for all queries managed by this QueryManager.
9447
+ */
9448
+ get metrics() {
9449
+ return this.#metrics;
9450
+ }
9451
+ addMetric(metric, value, ...args) {
9452
+ metric;
9453
+ this.#metrics[metric].add(value);
9454
+ const queryID = args[0];
9455
+ if (metric === "query-materialization-end-to-end") {
9456
+ const ast = args[1];
9457
+ if (this.#slowMaterializeThreshold !== void 0 && value > this.#slowMaterializeThreshold) {
9458
+ this.#lc.warn?.(
9459
+ "Slow query materialization (including server/network)",
9460
+ queryID,
9461
+ ast,
9462
+ value
9463
+ );
9464
+ } else {
9465
+ this.#lc.debug?.(
9466
+ "Materialized query (including server/network)",
9467
+ queryID,
9468
+ ast,
9469
+ value
9470
+ );
9401
9471
  }
9402
9472
  }
9473
+ let existing = this.#queryMetrics.get(queryID);
9474
+ if (!existing) {
9475
+ existing = newMetrics();
9476
+ this.#queryMetrics.set(queryID, existing);
9477
+ }
9478
+ existing[metric].add(value);
9479
+ }
9480
+ getQueryMetrics(queryID) {
9481
+ return this.#queryMetrics.get(queryID);
9403
9482
  }
9404
9483
  };
9484
+ function newMetrics() {
9485
+ return {
9486
+ "query-materialization-client": new TDigest(),
9487
+ "query-materialization-end-to-end": new TDigest(),
9488
+ "query-update-client": new TDigest()
9489
+ };
9490
+ }
9405
9491
 
9406
9492
  // ../zero-client/src/client/options.ts
9407
9493
  var updateNeededReasonTypeSchema = literalUnion(
@@ -9965,38 +10051,6 @@ var ZeroRep = class {
9965
10051
  }
9966
10052
  };
9967
10053
 
9968
- // ../shared/src/subscribable.ts
9969
- var Subscribable = class {
9970
- _listeners = /* @__PURE__ */ new Set();
9971
- /**
9972
- * Subscribe to the subscribable.
9973
- *
9974
- * @param listener - The listener to subscribe to.
9975
- * @returns A function to unsubscribe from the subscribable.
9976
- */
9977
- subscribe = (listener) => {
9978
- this._listeners.add(listener);
9979
- return () => {
9980
- this._listeners.delete(listener);
9981
- };
9982
- };
9983
- /**
9984
- * Notify all listeners.
9985
- *
9986
- * @param update - The update to notify listeners with.
9987
- */
9988
- notify = (update) => {
9989
- this._listeners.forEach((listener) => listener(update));
9990
- };
9991
- hasListeners = () => this._listeners.size > 0;
9992
- /**
9993
- * Unsubscribe all listeners.
9994
- */
9995
- cleanup = () => {
9996
- this._listeners.clear();
9997
- };
9998
- };
9999
-
10000
10054
  // ../zero-client/src/client/zero.ts
10001
10055
  var onSetConnectionStateSymbol = Symbol();
10002
10056
  var exposedToTestingSymbol = Symbol();
@@ -10227,8 +10281,7 @@ var Zero = class _Zero {
10227
10281
  replicacheMutators[key] = makeReplicacheMutator(
10228
10282
  lc,
10229
10283
  mutatorOrMutators,
10230
- schema,
10231
- slowMaterializeThreshold
10284
+ schema
10232
10285
  // Replicache expects mutators to only be able to return JSON
10233
10286
  // but Zero wraps the return with: `{server?: Promise<MutationResult>, client?: T}`
10234
10287
  );
@@ -10244,8 +10297,7 @@ var Zero = class _Zero {
10244
10297
  replicacheMutators[key] = makeReplicacheMutator(
10245
10298
  lc,
10246
10299
  mutator,
10247
- schema,
10248
- slowMaterializeThreshold
10300
+ schema
10249
10301
  );
10250
10302
  }
10251
10303
  continue;
@@ -10279,12 +10331,12 @@ var Zero = class _Zero {
10279
10331
  lc,
10280
10332
  this.#ivmMain,
10281
10333
  (ast, ttl, gotCallback) => this.#queryManager.addLegacy(ast, ttl, gotCallback),
10282
- (queryName, queryArgs, ttl, gotCallback) => this.#queryManager.addCustom(queryName, queryArgs, ttl, gotCallback),
10334
+ (customQueryID, ttl, gotCallback) => this.#queryManager.addCustom(customQueryID, ttl, gotCallback),
10283
10335
  (ast, ttl) => this.#queryManager.updateLegacy(ast, ttl),
10284
- (name, args, ttl) => this.#queryManager.updateCustom(name, args, ttl),
10336
+ (customQueryID, ttl) => this.#queryManager.updateCustom(customQueryID, ttl),
10285
10337
  () => this.#queryManager.flushBatch(),
10286
10338
  batchViewUpdates,
10287
- slowMaterializeThreshold,
10339
+ this.#addMetric,
10288
10340
  assertValidRunOptions2
10289
10341
  );
10290
10342
  this.queryDelegate = this.#zeroContext;
@@ -10376,7 +10428,8 @@ var Zero = class _Zero {
10376
10428
  (msg) => this.#send(msg),
10377
10429
  rep.experimentalWatch.bind(rep),
10378
10430
  maxRecentQueries,
10379
- options.queryChangeThrottleMs ?? DEFAULT_QUERY_CHANGE_THROTTLE_MS
10431
+ options.queryChangeThrottleMs ?? DEFAULT_QUERY_CHANGE_THROTTLE_MS,
10432
+ slowMaterializeThreshold
10380
10433
  );
10381
10434
  this.#clientToServer = clientToServer(schema.tables);
10382
10435
  this.#deleteClientsManager = new DeleteClientsManager(
@@ -11315,13 +11368,26 @@ var Zero = class _Zero {
11315
11368
  */
11316
11369
  async inspect() {
11317
11370
  BUNDLE_SIZE: {
11318
- const m = await import("./inspector-AF3UI76B.js");
11319
- return m.newInspector(this.#rep, this.#schema, async () => {
11320
- await this.#connectResolver.promise;
11321
- return this.#socket;
11322
- });
11371
+ const m = await import("./inspector-RB55U26N.js");
11372
+ return m.newInspector(
11373
+ this.#rep,
11374
+ this.#queryManager,
11375
+ this.#schema,
11376
+ async () => {
11377
+ await this.#connectResolver.promise;
11378
+ return this.#socket;
11379
+ }
11380
+ );
11323
11381
  }
11324
11382
  }
11383
+ #addMetric = (metric, value, ...args) => {
11384
+ const isQueryMetric = (metric2) => metric2.startsWith("query-");
11385
+ if (isQueryMetric(metric)) {
11386
+ this.#queryManager.addMetric(metric, value, ...args);
11387
+ } else {
11388
+ unreachable(metric);
11389
+ }
11390
+ };
11325
11391
  };
11326
11392
  var OnlineManager = class extends Subscribable {
11327
11393
  #online = false;
@@ -11468,4 +11534,4 @@ export {
11468
11534
  update_needed_reason_type_enum_exports,
11469
11535
  Zero
11470
11536
  };
11471
- //# sourceMappingURL=chunk-QVKOYV54.js.map
11537
+ //# sourceMappingURL=chunk-YTS56A64.js.map