flongo 1.4.0 → 1.6.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.
@@ -131,6 +131,26 @@ export declare class FlongoCollection<T> {
131
131
  * @param clientId - Optional client ID for audit trail
132
132
  */
133
133
  batchCreate(attributes: T[], clientId?: string): Promise<string[]>;
134
+ /**
135
+ * Inserts a document if no document with the same _id exists; otherwise does nothing.
136
+ * Race-safe "first writer wins" semantics — ideal for cache-through writes.
137
+ * @param attributes - Document data including _id
138
+ * @param clientId - Optional client ID for audit trail
139
+ * @returns Promise resolving to the document (newly created or existing)
140
+ */
141
+ createIfNotExists(attributes: T & {
142
+ _id: string;
143
+ }, clientId?: string): Promise<Entity & T>;
144
+ /**
145
+ * Inserts a document if no document with the same _id exists; otherwise overwrites it.
146
+ * Race-safe "last writer wins" semantics.
147
+ * @param attributes - Document data including _id
148
+ * @param clientId - Optional client ID for audit trail
149
+ * @returns Promise resolving to the document (newly created or updated)
150
+ */
151
+ createOrUpdate(attributes: T & {
152
+ _id: string;
153
+ }, clientId?: string): Promise<Entity & T>;
134
154
  /**
135
155
  * Updates multiple documents matching the query
136
156
  * @param attributes - Fields to update
@@ -256,6 +256,35 @@ class FlongoCollection {
256
256
  });
257
257
  return Object.values(result.insertedIds).map((id) => id.toString());
258
258
  }
259
+ /**
260
+ * Inserts a document if no document with the same _id exists; otherwise does nothing.
261
+ * Race-safe "first writer wins" semantics — ideal for cache-through writes.
262
+ * @param attributes - Document data including _id
263
+ * @param clientId - Optional client ID for audit trail
264
+ * @returns Promise resolving to the document (newly created or existing)
265
+ */
266
+ async createIfNotExists(attributes, clientId) {
267
+ const { _id, ...rest } = attributes;
268
+ const now = Date.now();
269
+ const result = await this.collection.findOneAndUpdate({ _id }, { $setOnInsert: { ...rest, createdBy: clientId, createdAt: now, updatedAt: now } }, { upsert: true, returnDocument: 'after' });
270
+ return this.toEntity(result);
271
+ }
272
+ /**
273
+ * Inserts a document if no document with the same _id exists; otherwise overwrites it.
274
+ * Race-safe "last writer wins" semantics.
275
+ * @param attributes - Document data including _id
276
+ * @param clientId - Optional client ID for audit trail
277
+ * @returns Promise resolving to the document (newly created or updated)
278
+ */
279
+ async createOrUpdate(attributes, clientId) {
280
+ const { _id, createdAt, createdBy, updatedAt, updatedBy, ...rest } = attributes;
281
+ const now = Date.now();
282
+ const result = await this.collection.findOneAndUpdate({ _id }, {
283
+ $set: { ...rest, updatedAt: now, updatedBy: clientId },
284
+ $setOnInsert: { createdAt: now, createdBy: clientId }
285
+ }, { upsert: true, returnDocument: 'after' });
286
+ return this.toEntity(result);
287
+ }
259
288
  // ===========================================
260
289
  // UPDATE OPERATIONS
261
290
  // ===========================================
@@ -214,6 +214,15 @@ export declare class FlongoQuery implements ICollectionQuery {
214
214
  * @returns This query instance for chaining
215
215
  */
216
216
  geoWithin(bounds?: Bounds): FlongoQuery;
217
+ /**
218
+ * Performs a proximity query using MongoDB's $near operator
219
+ * Requires a 2dsphere index on the target field
220
+ * Results are automatically sorted by distance (nearest first)
221
+ * @param center - Center point coordinates
222
+ * @param maxDistanceMeters - Maximum distance in meters
223
+ * @returns This query instance for chaining
224
+ */
225
+ near(center: Coordinates, maxDistanceMeters: number): FlongoQuery;
217
226
  /**
218
227
  * Sets the field and direction for sorting results
219
228
  * @param field - Field name to sort by
@@ -330,6 +330,24 @@ class FlongoQuery {
330
330
  }
331
331
  return this;
332
332
  }
333
+ /**
334
+ * Performs a proximity query using MongoDB's $near operator
335
+ * Requires a 2dsphere index on the target field
336
+ * Results are automatically sorted by distance (nearest first)
337
+ * @param center - Center point coordinates
338
+ * @param maxDistanceMeters - Maximum distance in meters
339
+ * @returns This query instance for chaining
340
+ */
341
+ near(center, maxDistanceMeters) {
342
+ this.set("$near", {
343
+ $geometry: {
344
+ type: "Point",
345
+ coordinates: [center.longitude, center.latitude]
346
+ },
347
+ $maxDistance: maxDistanceMeters
348
+ });
349
+ return this;
350
+ }
333
351
  // ===========================================
334
352
  // SORTING
335
353
  // ===========================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flongo",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "description": "Firestore-like fluent query API for MongoDB",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",