@ztimson/momentum 1.3.0 → 1.4.0

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/dist/data.d.ts CHANGED
@@ -1,12 +1,22 @@
1
1
  import { Unsubscribe } from '@ztimson/utils';
2
2
  import { Meta, PathEventEmitter } from './core';
3
3
  import { Momentum } from './momentum';
4
+ /** Comparison operators for filters */
5
+ export type FilterOperator = '=' | '!=' | '>' | '>=' | '<' | '<=' | 'in' | 'nin' | 'regex' | 'exists';
6
+ /** Filter value - primitive for equality or [operator, value] for comparison */
7
+ export type FilterValue<T = any> = T | [FilterOperator, T];
8
+ /** Filter object with comparison support */
9
+ export type Filter<T = any> = {
10
+ [K in keyof T]?: FilterValue<T[K]>;
11
+ } & {
12
+ [key: string]: FilterValue;
13
+ };
4
14
  /** Generic MongoDB document */
5
15
  export type Document<T> = Meta & T;
6
16
  /** Raw MongoDB query */
7
17
  export type RawQuery = {
8
18
  /** Query operation type */
9
- operand: 'delete' | 'deleteOne' | 'find' | 'findOne' | 'insertOne' | 'replaceOne' | 'update' | 'updateOne';
19
+ operand: 'deleteMany' | 'deleteOne' | 'findMany' | 'findOne' | 'insertMany' | 'insertOne' | 'replaceMany' | 'replaceOne' | 'updateMany' | 'updateOne';
10
20
  /** Filter affected documents */
11
21
  filter?: any;
12
22
  /** Query */
@@ -36,7 +46,8 @@ export declare class Data extends PathEventEmitter {
36
46
  * @param {number} id Document ID
37
47
  * @return {Promise<void>} Returns once complete
38
48
  */
39
- delete(collection: string, id: number): Promise<number>;
49
+ delete(collection: string, id: number): Promise<number[]>;
50
+ delete<T>(collection: string, filter: Filter<T>): Promise<number[]>;
40
51
  /**
41
52
  * Read collection/document
42
53
  * @param {string} collection target collection/document
@@ -44,14 +55,18 @@ export declare class Data extends PathEventEmitter {
44
55
  */
45
56
  read<T extends Meta>(collection: string): Promise<T[]>;
46
57
  read<T extends Meta>(collection: string, id: number): Promise<T>;
58
+ read<T extends Meta>(collection: string, filter: Filter<T>): Promise<T[]>;
47
59
  /**
48
60
  * Update document in collection
49
61
  * @param {string} collection Target collection
50
62
  * @param {Document<T>} document Document to update
51
- * @param {boolean} append Append or replace existing document
52
- * @return {Promise<Document<T>>} New saved document
63
+ * @param {object} options Filter and append options
64
+ * @return {Promise<Document<T> | Document<T>[]>} Updated document(s)
53
65
  */
54
- update<T>(collection: string, document: Document<T>, append?: boolean): Promise<Document<T>>;
66
+ update<T>(collection: string, document: Document<T>, options?: {
67
+ filter?: Filter<T>;
68
+ append?: boolean;
69
+ }): Promise<Document<T> | Document<T>[]>;
55
70
  /**
56
71
  * Create raw MongoDB query
57
72
  * @param {string} collection Target collection name
@@ -1 +1 @@
1
- {"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../src/data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAC,KAAK,IAAI,EAAE,gBAAgB,EAAM,MAAM,QAAQ,CAAC;AACxD,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AAEpC,+BAA+B;AAC/B,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;AAEnC,wBAAwB;AACxB,MAAM,MAAM,QAAQ,GAAG;IACtB,2BAA2B;IAC3B,OAAO,EAAE,QAAQ,GAAG,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,YAAY,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC3G,gCAAgC;IAChC,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,YAAY;IACZ,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,gCAAgC;IAChC,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,4BAA4B;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB,CAAA;AAED,qCAAqC;AACrC,qBAAa,IAAK,SAAQ,gBAAgB;IAG7B,SAAS,CAAC,QAAQ,EAAE,QAAQ;IAFxC,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAA;KAAC,CAAM;gBAE5C,QAAQ,EAAE,QAAQ;IAIxC;;;;;OAKG;IACH,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAY1E;;;;;OAKG;IACG,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAU7D;;;;OAIG;IACH,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IACtD,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAShE;;;;;;OAMG;IACH,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAY5F;;;;;OAKG;IACH,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IASzD;;;;;;OAMG;IACH,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,GAAE;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAM,GAAG,WAAW;CAmBtG"}
1
+ {"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../src/data.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -165,7 +165,7 @@
165
165
  function requireDist() {
166
166
  if (hasRequiredDist) return dist;
167
167
  hasRequiredDist = 1;
168
- (function(exports$1) {
168
+ (function(exports3) {
169
169
  var __createBinding = dist && dist.__createBinding || (Object.create ? (function(o, m, k, k2) {
170
170
  if (k2 === void 0) k2 = k;
171
171
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -179,12 +179,12 @@
179
179
  if (k2 === void 0) k2 = k;
180
180
  o[k2] = m[k];
181
181
  }));
182
- var __exportStar = dist && dist.__exportStar || function(m, exports$12) {
183
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$12, p)) __createBinding(exports$12, m, p);
182
+ var __exportStar = dist && dist.__exportStar || function(m, exports22) {
183
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports22, p)) __createBinding(exports22, m, p);
184
184
  };
185
- Object.defineProperty(exports$1, "__esModule", { value: true });
186
- __exportStar(requirePersist(), exports$1);
187
- __exportStar(requireMemoryStorage(), exports$1);
185
+ Object.defineProperty(exports3, "__esModule", { value: true });
186
+ __exportStar(requirePersist(), exports3);
187
+ __exportStar(requireMemoryStorage(), exports3);
188
188
  })(dist);
189
189
  return dist;
190
190
  }
@@ -1331,7 +1331,7 @@
1331
1331
  let temp = p.split("/").filter((p2) => !!p2);
1332
1332
  this.module = temp.splice(0, 1)[0] || "";
1333
1333
  this.path = temp.join("/");
1334
- this.dir = temp.length > 2 ? temp.slice(0, -1).join("/") : "";
1334
+ this.dir = temp.length > 1 ? temp.slice(0, -1).join("/") : "";
1335
1335
  this.fullPath = `${this.module}${this.module && this.path ? "/" : ""}${this.path}`;
1336
1336
  this.name = temp.pop() || "";
1337
1337
  this.hasGlob = this.fullPath.includes("*");
@@ -3145,25 +3145,27 @@ Must be either: call, email or sms`);
3145
3145
  return resp;
3146
3146
  });
3147
3147
  }
3148
- /**
3149
- * Delete document from collection
3150
- * @param {string} collection Target collection
3151
- * @param {number} id Document ID
3152
- * @return {Promise<void>} Returns once complete
3153
- */
3154
- async delete(collection, id) {
3155
- if (!collection || !id) throw new Error("Cannot delete document, missing collection or ID");
3156
- const count = await this.momentum.api.request({
3157
- url: `api/` + PES`data/${collection}/${id}`,
3158
- method: "DELETE"
3159
- });
3160
- if (count) this.emit(PES`data/${collection}/${id}:d`, id);
3161
- return count;
3148
+ async delete(collection, filter) {
3149
+ if (!collection || !filter) throw new Error("Cannot delete document, missing collection or filter");
3150
+ const pk = typeof filter == "object" ? filter?.["_id"] ?? null : filter;
3151
+ const q = typeof filter == "object" ? JSON.stringify(filter) : null;
3152
+ const url = `api/data/${collection}${pk ? `/${pk}` : ""}${q ? `?q=${encodeURIComponent(q)}` : ""}`;
3153
+ const ids = await this.momentum.api.request({ url, method: "DELETE" });
3154
+ ids.forEach((id) => this.emit(PES`data/${collection}/${id}:d`, id));
3155
+ return ids;
3162
3156
  }
3163
- read(collection, id) {
3157
+ read(collection, filter) {
3164
3158
  if (!collection) throw new Error("Cannot read documents, missing collection");
3165
- return this.momentum.api.request({ url: `api/` + PES`data/${collection}/${id}` }).then((resp) => {
3166
- this.emit(PES`data/${collection}/${id}:r`, collection, resp);
3159
+ const pk = typeof filter == "object" ? filter?.["_id"] ?? null : filter;
3160
+ const q = typeof filter == "object" ? JSON.stringify(filter) : null;
3161
+ const url = `api/data/${collection}${pk ? `/${pk}` : ""}${q ? `?q=${encodeURIComponent(q)}` : ""}`;
3162
+ return this.momentum.api.request({ url }).then((resp) => {
3163
+ if (Array.isArray(resp)) {
3164
+ if (!q) this.emit(PES`data/${collection}:r`, collection, resp);
3165
+ else resp.forEach((r) => this.emit(PES`data/${collection}/${r._id}:r`, collection, resp));
3166
+ } else {
3167
+ this.emit(PES`data/${collection}/${resp._id}:r`, collection, resp);
3168
+ }
3167
3169
  return resp;
3168
3170
  });
3169
3171
  }
@@ -3171,17 +3173,21 @@ Must be either: call, email or sms`);
3171
3173
  * Update document in collection
3172
3174
  * @param {string} collection Target collection
3173
3175
  * @param {Document<T>} document Document to update
3174
- * @param {boolean} append Append or replace existing document
3175
- * @return {Promise<Document<T>>} New saved document
3176
+ * @param {object} options Filter and append options
3177
+ * @return {Promise<Document<T> | Document<T>[]>} Updated document(s)
3176
3178
  */
3177
- update(collection, document2, append) {
3179
+ update(collection, document2, options = {}) {
3178
3180
  if (!collection || !document2) throw new Error("Cannot update document, missing collection or document");
3181
+ const pk = options.filter ? options.filter?.["_id"] ?? document2._id : document2._id;
3182
+ const q = options.filter && !options.filter?.["_id"] ? JSON.stringify(options.filter) : null;
3183
+ const url = `api/data/${collection}${pk ? `/${pk}` : ""}${q ? `?q=${encodeURIComponent(q)}` : ""}`;
3179
3184
  return this.momentum.api.request({
3180
- url: `api/` + PES`data/${collection}/${document2._id}`,
3181
- method: append ? "PATCH" : "PUT",
3185
+ url,
3186
+ method: options.append === false ? "PUT" : "PATCH",
3182
3187
  body: document2
3183
3188
  }).then((resp) => {
3184
- this.emit(PES`data/${collection}/${document2._id}:u`, resp);
3189
+ if (Array.isArray(resp)) resp.forEach((r) => this.emit(PES`data/${collection}/${r._id}:u`, r));
3190
+ else this.emit(PES`data/${collection}/${resp._id}:u`, resp);
3185
3191
  return resp;
3186
3192
  });
3187
3193
  }
@@ -3216,12 +3222,12 @@ Must be either: call, email or sms`);
3216
3222
  callback(cache.all());
3217
3223
  });
3218
3224
  if (opts.reload == void 0 || opts.reload) this.read(path);
3219
- if (!this.subscribers.length) this.momentum.socket?.subscribe(e);
3225
+ if (!Object.keys(this.subscribers).length) this.momentum.socket?.subscribe(e);
3220
3226
  const key = Object.keys(this.subscribers).length.toString();
3221
3227
  this.subscribers[key] = () => {
3222
3228
  unsubscribe();
3223
3229
  delete this.subscribers[key];
3224
- if (!this.subscribers.length) this.momentum.socket?.unsubscribe(e);
3230
+ if (!Object.keys(this.subscribers).length) this.momentum.socket?.unsubscribe(e);
3225
3231
  };
3226
3232
  return this.subscribers[key];
3227
3233
  }
@@ -4250,7 +4256,7 @@ ${log}`;
4250
4256
  }
4251
4257
  momentum;
4252
4258
  }
4253
- const version = "1.3.0";
4259
+ const version = "1.4.0";
4254
4260
  class WebRtc extends PathEventEmitter {
4255
4261
  constructor(momentum) {
4256
4262
  super("webrtc");
package/dist/index.mjs CHANGED
@@ -161,7 +161,7 @@ var hasRequiredDist;
161
161
  function requireDist() {
162
162
  if (hasRequiredDist) return dist;
163
163
  hasRequiredDist = 1;
164
- (function(exports$1) {
164
+ (function(exports) {
165
165
  var __createBinding = dist && dist.__createBinding || (Object.create ? (function(o, m, k, k2) {
166
166
  if (k2 === void 0) k2 = k;
167
167
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -175,12 +175,12 @@ function requireDist() {
175
175
  if (k2 === void 0) k2 = k;
176
176
  o[k2] = m[k];
177
177
  }));
178
- var __exportStar = dist && dist.__exportStar || function(m, exports$12) {
179
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$12, p)) __createBinding(exports$12, m, p);
178
+ var __exportStar = dist && dist.__exportStar || function(m, exports2) {
179
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p)) __createBinding(exports2, m, p);
180
180
  };
181
- Object.defineProperty(exports$1, "__esModule", { value: true });
182
- __exportStar(requirePersist(), exports$1);
183
- __exportStar(requireMemoryStorage(), exports$1);
181
+ Object.defineProperty(exports, "__esModule", { value: true });
182
+ __exportStar(requirePersist(), exports);
183
+ __exportStar(requireMemoryStorage(), exports);
184
184
  })(dist);
185
185
  return dist;
186
186
  }
@@ -1327,7 +1327,7 @@ class PathEvent {
1327
1327
  let temp = p.split("/").filter((p2) => !!p2);
1328
1328
  this.module = temp.splice(0, 1)[0] || "";
1329
1329
  this.path = temp.join("/");
1330
- this.dir = temp.length > 2 ? temp.slice(0, -1).join("/") : "";
1330
+ this.dir = temp.length > 1 ? temp.slice(0, -1).join("/") : "";
1331
1331
  this.fullPath = `${this.module}${this.module && this.path ? "/" : ""}${this.path}`;
1332
1332
  this.name = temp.pop() || "";
1333
1333
  this.hasGlob = this.fullPath.includes("*");
@@ -3141,25 +3141,27 @@ class Data extends PathEventEmitter {
3141
3141
  return resp;
3142
3142
  });
3143
3143
  }
3144
- /**
3145
- * Delete document from collection
3146
- * @param {string} collection Target collection
3147
- * @param {number} id Document ID
3148
- * @return {Promise<void>} Returns once complete
3149
- */
3150
- async delete(collection, id) {
3151
- if (!collection || !id) throw new Error("Cannot delete document, missing collection or ID");
3152
- const count = await this.momentum.api.request({
3153
- url: `api/` + PES`data/${collection}/${id}`,
3154
- method: "DELETE"
3155
- });
3156
- if (count) this.emit(PES`data/${collection}/${id}:d`, id);
3157
- return count;
3144
+ async delete(collection, filter) {
3145
+ if (!collection || !filter) throw new Error("Cannot delete document, missing collection or filter");
3146
+ const pk = typeof filter == "object" ? filter?.["_id"] ?? null : filter;
3147
+ const q = typeof filter == "object" ? JSON.stringify(filter) : null;
3148
+ const url = `api/data/${collection}${pk ? `/${pk}` : ""}${q ? `?q=${encodeURIComponent(q)}` : ""}`;
3149
+ const ids = await this.momentum.api.request({ url, method: "DELETE" });
3150
+ ids.forEach((id) => this.emit(PES`data/${collection}/${id}:d`, id));
3151
+ return ids;
3158
3152
  }
3159
- read(collection, id) {
3153
+ read(collection, filter) {
3160
3154
  if (!collection) throw new Error("Cannot read documents, missing collection");
3161
- return this.momentum.api.request({ url: `api/` + PES`data/${collection}/${id}` }).then((resp) => {
3162
- this.emit(PES`data/${collection}/${id}:r`, collection, resp);
3155
+ const pk = typeof filter == "object" ? filter?.["_id"] ?? null : filter;
3156
+ const q = typeof filter == "object" ? JSON.stringify(filter) : null;
3157
+ const url = `api/data/${collection}${pk ? `/${pk}` : ""}${q ? `?q=${encodeURIComponent(q)}` : ""}`;
3158
+ return this.momentum.api.request({ url }).then((resp) => {
3159
+ if (Array.isArray(resp)) {
3160
+ if (!q) this.emit(PES`data/${collection}:r`, collection, resp);
3161
+ else resp.forEach((r) => this.emit(PES`data/${collection}/${r._id}:r`, collection, resp));
3162
+ } else {
3163
+ this.emit(PES`data/${collection}/${resp._id}:r`, collection, resp);
3164
+ }
3163
3165
  return resp;
3164
3166
  });
3165
3167
  }
@@ -3167,17 +3169,21 @@ class Data extends PathEventEmitter {
3167
3169
  * Update document in collection
3168
3170
  * @param {string} collection Target collection
3169
3171
  * @param {Document<T>} document Document to update
3170
- * @param {boolean} append Append or replace existing document
3171
- * @return {Promise<Document<T>>} New saved document
3172
+ * @param {object} options Filter and append options
3173
+ * @return {Promise<Document<T> | Document<T>[]>} Updated document(s)
3172
3174
  */
3173
- update(collection, document2, append) {
3175
+ update(collection, document2, options = {}) {
3174
3176
  if (!collection || !document2) throw new Error("Cannot update document, missing collection or document");
3177
+ const pk = options.filter ? options.filter?.["_id"] ?? document2._id : document2._id;
3178
+ const q = options.filter && !options.filter?.["_id"] ? JSON.stringify(options.filter) : null;
3179
+ const url = `api/data/${collection}${pk ? `/${pk}` : ""}${q ? `?q=${encodeURIComponent(q)}` : ""}`;
3175
3180
  return this.momentum.api.request({
3176
- url: `api/` + PES`data/${collection}/${document2._id}`,
3177
- method: append ? "PATCH" : "PUT",
3181
+ url,
3182
+ method: options.append === false ? "PUT" : "PATCH",
3178
3183
  body: document2
3179
3184
  }).then((resp) => {
3180
- this.emit(PES`data/${collection}/${document2._id}:u`, resp);
3185
+ if (Array.isArray(resp)) resp.forEach((r) => this.emit(PES`data/${collection}/${r._id}:u`, r));
3186
+ else this.emit(PES`data/${collection}/${resp._id}:u`, resp);
3181
3187
  return resp;
3182
3188
  });
3183
3189
  }
@@ -3212,12 +3218,12 @@ class Data extends PathEventEmitter {
3212
3218
  callback(cache.all());
3213
3219
  });
3214
3220
  if (opts.reload == void 0 || opts.reload) this.read(path);
3215
- if (!this.subscribers.length) this.momentum.socket?.subscribe(e);
3221
+ if (!Object.keys(this.subscribers).length) this.momentum.socket?.subscribe(e);
3216
3222
  const key = Object.keys(this.subscribers).length.toString();
3217
3223
  this.subscribers[key] = () => {
3218
3224
  unsubscribe();
3219
3225
  delete this.subscribers[key];
3220
- if (!this.subscribers.length) this.momentum.socket?.unsubscribe(e);
3226
+ if (!Object.keys(this.subscribers).length) this.momentum.socket?.unsubscribe(e);
3221
3227
  };
3222
3228
  return this.subscribers[key];
3223
3229
  }
@@ -4246,7 +4252,7 @@ class Static extends Storage {
4246
4252
  }
4247
4253
  momentum;
4248
4254
  }
4249
- const version = "1.3.0";
4255
+ const version = "1.4.0";
4250
4256
  class WebRtc extends PathEventEmitter {
4251
4257
  constructor(momentum) {
4252
4258
  super("webrtc");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ztimson/momentum",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Client library for momentum",
5
5
  "keywords": [
6
6
  "Momentum"
@@ -33,7 +33,7 @@
33
33
  "postbuild": "npm run build:docs && node -e \"const fs=require('fs');fs.cpSync('dist/index.mjs','../server/public/momentum.mjs');fs.cpSync('dist/index.js','../server/public/momentum.js');fs.cpSync('dist/momentum.worker.mjs','../server/public/momentum.worker.mjs')\""
34
34
  },
35
35
  "dependencies": {
36
- "@ztimson/utils": "^0.29.4"
36
+ "@ztimson/utils": "^0.29.5"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^22.5.4",