@rebasepro/server-mongo 0.14.1-canary.g7e666eb → 0.14.1

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.
@@ -79,6 +79,17 @@ export declare class MongoConditionBuilder {
79
79
  searchString?: string;
80
80
  properties?: CollectionConfig["properties"];
81
81
  }): Filter<Document>;
82
+ /**
83
+ * The primary key's name in a stored document.
84
+ *
85
+ * Rows leave this driver with `_id` renamed to `id` — see
86
+ * `MongoDataService.documentToRow` — so `id` is the only name a caller ever
87
+ * sees, and the one the SDK's own examples use for a tie-breaker. A sort
88
+ * document naming `id` names a field no document has: Mongo does not
89
+ * complain, it just returns them in natural order, so `.orderBy("id")` read
90
+ * as "no sort at all" with a 200 to go with it.
91
+ */
92
+ private static readonly ID_FIELD;
82
93
  /**
83
94
  * Build MongoDB sort options from Rebase options
84
95
  *
@@ -86,6 +97,15 @@ export declare class MongoConditionBuilder {
86
97
  * a multi-key sort is expressed directly: the keys are applied in insertion
87
98
  * order, each breaking ties on the one before it.
88
99
  *
100
+ * The id closes every sort, descending, for the same reason the Postgres
101
+ * driver appends `id DESC`: it is what makes the ordering *total*. Without
102
+ * it, two rows sharing a sort value are returned in whatever order the
103
+ * engine pleases, and that order is free to differ between two executions of
104
+ * the same query — so paging by `offset` over a non-unique sort column
105
+ * repeats some rows and skips others. A single-column sort has always had
106
+ * this exposure here; a multi-key sort merely made it easier to reach, since
107
+ * the whole point of the later keys is that the earlier ones tie.
108
+ *
89
109
  * @param orderBy - Field to order by, or the `[field, direction]` list
90
110
  * @param order - Sort direction, for the single-field spelling
91
111
  * @returns MongoDB sort object
@@ -1 +1 @@
1
- {"version":3,"file":"MongoConditionBuilder.d.ts","sourceRoot":"","sources":["../../src/db/MongoConditionBuilder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAmB,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAiB,MAAM,kBAAkB,CAAC;AAElI,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAkD3C;;;;;GAKG;AACH,qBAAa,qBAAqB;IAC9B;;;;;OAKG;IACH,MAAM,CAAC,qBAAqB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACtD,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,GAC/C,MAAM,CAAC,QAAQ,CAAC,EAAE;IAqBrB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAwC7B;;;;;;OAMG;IACH,MAAM,CAAC,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAuBlG;;;;;;OAMG;IACH,MAAM,CAAC,qBAAqB,CACxB,YAAY,EAAE,MAAM,EAKpB,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC,GAC3C,MAAM,CAAC,QAAQ,CAAC,EAAE;IAkCrB;;;;;OAKG;IACH,MAAM,CAAC,wBAAwB,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAM7F;;;;;OAKG;IACH,MAAM,CAAC,uBAAuB,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAM5F;;;;;OAKG;IACH,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE;QACtD,MAAM,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAChD;;;;;WAKG;QACH,OAAO,CAAC,EAAE,gBAAgB,CAAC;QAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;KAC/C,GAAG,MAAM,CAAC,QAAQ,CAAC;IA8BpB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,SAAS,CACZ,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,EACjC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,GACvB,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS;CAYxC"}
1
+ {"version":3,"file":"MongoConditionBuilder.d.ts","sourceRoot":"","sources":["../../src/db/MongoConditionBuilder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAmB,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAiB,MAAM,kBAAkB,CAAC;AAElI,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAkD3C;;;;;GAKG;AACH,qBAAa,qBAAqB;IAC9B;;;;;OAKG;IACH,MAAM,CAAC,qBAAqB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACtD,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,GAC/C,MAAM,CAAC,QAAQ,CAAC,EAAE;IAqBrB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAwC7B;;;;;;OAMG;IACH,MAAM,CAAC,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAuBlG;;;;;;OAMG;IACH,MAAM,CAAC,qBAAqB,CACxB,YAAY,EAAE,MAAM,EAKpB,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC,GAC3C,MAAM,CAAC,QAAQ,CAAC,EAAE;IAkCrB;;;;;OAKG;IACH,MAAM,CAAC,wBAAwB,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAM7F;;;;;OAKG;IACH,MAAM,CAAC,uBAAuB,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAM5F;;;;;OAKG;IACH,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE;QACtD,MAAM,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAChD;;;;;WAKG;QACH,OAAO,CAAC,EAAE,gBAAgB,CAAC;QAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;KAC/C,GAAG,MAAM,CAAC,QAAQ,CAAC;IA8BpB;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAEzC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,MAAM,CAAC,SAAS,CACZ,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,EACjC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,GACvB,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS;CAkBxC"}
package/dist/index.es.js CHANGED
@@ -108,7 +108,7 @@ function likePatternToRegExp(pattern, caseInsensitive) {
108
108
  * Provides static methods to translate Rebase filter conditions
109
109
  * to MongoDB query filters.
110
110
  */
111
- var MongoConditionBuilder = class {
111
+ var MongoConditionBuilder = class MongoConditionBuilder {
112
112
  /**
113
113
  * Build MongoDB filter conditions from Rebase FilterValues
114
114
  *
@@ -238,12 +238,32 @@ var MongoConditionBuilder = class {
238
238
  return this.combineConditionsWithAnd(conditions) ?? {};
239
239
  }
240
240
  /**
241
+ * The primary key's name in a stored document.
242
+ *
243
+ * Rows leave this driver with `_id` renamed to `id` — see
244
+ * `MongoDataService.documentToRow` — so `id` is the only name a caller ever
245
+ * sees, and the one the SDK's own examples use for a tie-breaker. A sort
246
+ * document naming `id` names a field no document has: Mongo does not
247
+ * complain, it just returns them in natural order, so `.orderBy("id")` read
248
+ * as "no sort at all" with a 200 to go with it.
249
+ */
250
+ static ID_FIELD = "_id";
251
+ /**
241
252
  * Build MongoDB sort options from Rebase options
242
253
  *
243
254
  * A Mongo sort document is already an ordered map of field to direction, so
244
255
  * a multi-key sort is expressed directly: the keys are applied in insertion
245
256
  * order, each breaking ties on the one before it.
246
257
  *
258
+ * The id closes every sort, descending, for the same reason the Postgres
259
+ * driver appends `id DESC`: it is what makes the ordering *total*. Without
260
+ * it, two rows sharing a sort value are returned in whatever order the
261
+ * engine pleases, and that order is free to differ between two executions of
262
+ * the same query — so paging by `offset` over a non-unique sort column
263
+ * repeats some rows and skips others. A single-column sort has always had
264
+ * this exposure here; a multi-key sort merely made it easier to reach, since
265
+ * the whole point of the later keys is that the earlier ones tie.
266
+ *
247
267
  * @param orderBy - Field to order by, or the `[field, direction]` list
248
268
  * @param order - Sort direction, for the single-field spelling
249
269
  * @returns MongoDB sort object
@@ -252,7 +272,11 @@ var MongoConditionBuilder = class {
252
272
  const keys = normalizeDriverOrderBy(orderBy, order);
253
273
  if (!keys) return void 0;
254
274
  const sort = {};
255
- for (const [field, direction] of keys) if (!(field in sort)) sort[field] = direction === "desc" ? -1 : 1;
275
+ for (const [field, direction] of keys) {
276
+ const key = field === "id" ? MongoConditionBuilder.ID_FIELD : field;
277
+ if (!(key in sort)) sort[key] = direction === "desc" ? -1 : 1;
278
+ }
279
+ if (!(MongoConditionBuilder.ID_FIELD in sort)) sort[MongoConditionBuilder.ID_FIELD] = -1;
256
280
  return sort;
257
281
  }
258
282
  };