@ztimson/momentum 1.3.1 → 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
@@ -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;
3162
- }
3163
- read(collection, id) {
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;
3156
+ }
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.1";
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
@@ -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;
3158
- }
3159
- read(collection, id) {
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;
3152
+ }
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.1";
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.1",
3
+ "version": "1.4.0",
4
4
  "description": "Client library for momentum",
5
5
  "keywords": [
6
6
  "Momentum"