coll-fns 1.2.0 → 1.3.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/README.md CHANGED
@@ -47,6 +47,9 @@ Stop repeating business logic all over your code base. Define hooks on collectio
47
47
  - [`insert(Coll, doc)`](#insertcoll-doc)
48
48
  - [`update(Coll, selector, modifier, options)`](#updatecoll-selector-modifier-options)
49
49
  - [`remove(Coll, selector)`](#removecoll-selector)
50
+ - [`configurePool(options)`](#configurepooloptions)
51
+ - [Default behavior](#default-behavior)
52
+ - [Options](#options)
50
53
  - [Hook best practices](#hook-best-practices)
51
54
  - [License](#license)
52
55
 
@@ -947,12 +950,57 @@ Although arguments can be mutated, it is not the main purpose of these hooks. Mu
947
950
 
948
951
  ### After hooks
949
952
 
950
- These hooks run **after** the write operation completes and are **fire-and-forget** (not awaited). They should not throw errors that should get back to the caller.
953
+ These hooks run **after** the write operation completes and are **fire-and-forget** (not awaited by the caller of the collection function). They are usually used to trigger side-effects. They should not throw errors that should get back to the caller.
951
954
 
952
955
  - **`onInserted`**: Runs after a document is inserted. Receives `(doc)`.
953
956
  - **`onUpdated`**: Runs after a document is updated. Receives `(afterDoc, beforeDoc)`.
954
957
  - **`onRemoved`**: Runs after a document is removed. Receives `(doc)`.
955
958
 
959
+ **IMPORTANT!**
960
+
961
+ 1. These hooks **might create incoherent state** when used as a denormalization technique (a common and helpful use case) if a downstream update fails. It is **NOT inherent to `coll-fns`**, but rather to eventual consistent database designs. Even if the after hooks were awaited, errors would not rollback prior successful updates.
962
+
963
+ 2. Although hooks can define `onError` callbacks, if `fn` executes async code, **it MUST await it or return it as a promise**. Otherwise, `onError` callback will never get fired because the function will be running in a separate promise context. If `fn` starts async work and doesn’t return/await it, any error will become an **unhandled rejection (and may crash the process)**.
964
+
965
+ ❌ **Wrong**
966
+
967
+ ```js
968
+ hook(Coll, {
969
+ fn(doc) {
970
+ update(/* Some other collection */); // not awaited / not returned
971
+ },
972
+ });
973
+ ```
974
+
975
+ Might crash the process!
976
+
977
+ ```
978
+ UnhandledPromiseRejection: Error: Validation failed
979
+ at beforeUpdate (.../src/hooks.js:42:11)
980
+ at update (.../src/update.js:128:7)
981
+ ...
982
+ ```
983
+
984
+ ✅ **Right**
985
+
986
+ ```js
987
+ hook(Coll, {
988
+ async fn(doc) {
989
+ await update(/* Some other collection */); // Awaited
990
+ },
991
+ });
992
+ ```
993
+
994
+ or
995
+
996
+ ```js
997
+ hook(Coll, {
998
+ fn(doc) {
999
+ return update(/* Some other collection */); // Returned promise
1000
+ },
1001
+ });
1002
+ ```
1003
+
956
1004
  ### Hook definition properties
957
1005
 
958
1006
  Each hook definition is an object with the following properties:
@@ -960,7 +1008,8 @@ Each hook definition is an object with the following properties:
960
1008
  ```js
961
1009
  {
962
1010
  /* Required. The function to execute.
963
- * Arguments depend on the hook type (see above). */
1011
+ * Arguments depend on the hook type (see above).
1012
+ * Can be either synchronous or asynchronous. */
964
1013
  fn(...args) { /* ... */ },
965
1014
 
966
1015
  /* Optional. Fields to fetch for the documents passed to the hook.
@@ -976,11 +1025,11 @@ Each hook definition is an object with the following properties:
976
1025
  * needed anyway to fetch their "after" versions). */
977
1026
  before: true,
978
1027
 
979
- /* Optional. Predicate that prevents the hook from running if it
1028
+ /* Optional. Synchronous predicate that prevents the hook from running if it
980
1029
  * returns a truthy value. Receives the same arguments as fn. */
981
1030
  unless(doc) { return doc.isBot; },
982
1031
 
983
- /* Optional. Predicate that allows the hook to run only if it
1032
+ /* Optional. Synchronous predicate that allows the hook to run only if it
984
1033
  * returns a truthy value. Receives the same arguments as fn. */
985
1034
  when(doc) { return doc.status === "pending"; },
986
1035
 
@@ -1165,6 +1214,66 @@ remove(Users, { inactive: true });
1165
1214
  3. Remove the documents
1166
1215
  4. Fire `onRemoved` hooks asynchronously with each removed document
1167
1216
 
1217
+ ## `configurePool(options)`
1218
+
1219
+ After hooks can generate significant background work, especially when they trigger cascading writes and more after hooks.
1220
+
1221
+ `coll-fns` uses an internal execution pool for fire-and-forget after hooks.
1222
+ You can configure this pool at startup.
1223
+
1224
+ `configurePool` must be called **before any after hook is processed**.
1225
+
1226
+ ### Default behavior
1227
+
1228
+ By default, the pool uses:
1229
+
1230
+ - `maxConcurrent: 10`
1231
+ - `maxPending: 250`
1232
+ - `onOverflow`: drop new call and warn in console
1233
+
1234
+ This prevents unbounded growth while allowing parallel processing.
1235
+
1236
+ ### Options
1237
+
1238
+ ```ts
1239
+ configurePool({
1240
+ maxConcurrent?: number; // >= 1
1241
+ maxPending?: number | Infinity; // >= 0 or Infinity
1242
+ onOverflow?: "drop" | "shift" | (pendings, call) => reorderedPendings | void;
1243
+ onError?: (error, call) => void;
1244
+ });
1245
+ ```
1246
+
1247
+ - `maxConcurrent`: maximum number of after hooks executed in parallel.
1248
+ - `maxPending`: maximum number of queued hooks waiting for execution.
1249
+ - `onOverflow`: policy to apply when pendings overflow
1250
+ - "drop": ignore the new call.
1251
+ - "shift": remove oldest pending call, enqueue the new one.
1252
+ - function: return a reordered/filtered pending list.
1253
+ - `onError`: called when a pooled call fails. If omitted, errors are logged.
1254
+
1255
+ **Example**
1256
+
1257
+ ```js
1258
+ import { configurePool } from "coll-fns";
1259
+
1260
+ /* Must be called BEFORE any after hook is processed. */
1261
+ configurePool({
1262
+ maxConcurrent: 20,
1263
+ maxPending: 1000,
1264
+ onOverflow: "shift",
1265
+ onError(error, call) {
1266
+ console.error("After-hook pool error:", error, call);
1267
+ },
1268
+ });
1269
+ ```
1270
+
1271
+ **Notes**
1272
+
1273
+ - This configuration is **startup-only**. Calling configurePool after processing starts throws.
1274
+ - If your workload is sensitive to ordering, keep maxConcurrent low or implement ordering constraints in your hook logic.
1275
+ - Tune maxConcurrent/maxPending based on your app’s throughput and memory profile.
1276
+
1168
1277
  ## Hook best practices
1169
1278
 
1170
1279
  <details>
package/dist/coll-fns.cjs CHANGED
@@ -1,2 +1,2 @@
1
- function n(){return n=Object.assign?Object.assign.bind():function(n){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var e in t)({}).hasOwnProperty.call(t,e)&&(n[e]=t[e])}return n},n.apply(null,arguments)}function r(n,r){if(null==n)return{};var t={};for(var e in n)if({}.hasOwnProperty.call(n,e)){if(-1!==r.indexOf(e))continue;t[e]=n[e]}return t}function t(n){var r=function(n){if("object"!=typeof n||!n)return n;var r=n[Symbol.toPrimitive];if(void 0!==r){var t=r.call(n,"string");if("object"!=typeof t)return t;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(n)}(n);return"symbol"==typeof r?r:r+""}var e={count:function(){throw new Error("'count' method must be defined with 'setProtocol'.")},findList:function(){throw new Error("'findList' method must be defined with 'setProtocol'.")},getName:function(){return""},getTransform:function(){},insert:function(){throw new Error("'insert' method must be defined with 'setProtocol'.")},remove:function(){throw new Error("'remove' method must be defined with 'setProtocol'.")},update:function(){throw new Error("'update' method must be defined with 'setProtocol'.")}},o=e;function i(n){return n?"function"==typeof n?n(o):"object"==typeof n?n:o:o}var u=function(){},f=function(n){return{}.toString.call(n).split(" ")[1].slice(0,-1).toLowerCase()},c=function(n){return Array.isArray(n)},l=function(n){return"function"==typeof n},a=function(n){return n&&!c(n)&&"object"===f(n)};function d(n){return l(null==n?void 0:n.then)}function s(n,r){return m(function(r){var t=r[0];return[n[t]||t,r[1]]},r)}function v(n,r){var t=n.split("."),e=t[0],o=function(n,r){(null==r||r>n.length)&&(r=n.length);for(var t=0,e=Array(r);t<r;t++)e[t]=n[t];return e}(t).slice(1),i=r[e];if(o.length<1)return i;var u=o.join(".");return a(i)?v(u,i):c(i)?i.flatMap(function(n){var r=v(u,n);return c(r)?r:[r]}):i}function p(n,r){if(void 0===r&&(r=u),c(n)){var t=n;return t.some(d)?Promise.all(t).then(function(n){return r(n,!0)}):r(t,!1)}return d(n)?n.then(function(n){return r(n,!0)}):r(n,!1)}function m(n,r){if(void 0===r)return function(r){return m(n,r)};if(c(r))return r.map(n);if(!a(r))throw new TypeError("'map' only works on array or plain object");return Object.fromEntries(Object.entries(r).map(n))}function h(n,r){if(void 0===r)return function(r){return h(n,r)};if(c(r))return r.filter(n);if(!a(r))throw new TypeError("'filter' only works on array or plain object");return Object.fromEntries(Object.entries(r).filter(n))}function y(n,r){try{n()}catch(n){l(r)&&r(n)}}var b=["array","function","object"],w=b.join("', '"),j=new Map,g=null;function _(n){return j.get(n)||{}}function O(){return g}var k=["+"];function E(n,r){return void 0===r&&(r=!1),a(n)?r?x(n):n:n?void 0:{}}function x(r,t){var e;if(!r)return r;var o=Object.keys(r);return o.some(function(n){return n.startsWith("$")})?t?((e={})[t]=r,e):r:o.reduce(function(e,o){var i=o.indexOf(".");if(i>=0){var u=o.slice(0,i),f=r[u];if(f&&!a(f))return e}var c,l=r[o],d=t?[t,o].join("."):o;return a(l)?n({},e,x(l,d)):n({},e,((c={})[d]=!!l,c))},void 0)}function C(e,o){var i;if(void 0===o&&(o={}),!a(e))return{_:E(e)};var u=function(e,o){void 0===o&&(o={});var i=Object.keys(o),u=O();if(u){var f=e[u],c=r(e,[u].map(t));return n(f?{"+":h(function(n){return i.includes(n[0])},f)}:{"+":void 0},c)}return Object.entries(e).reduce(function(r,t){var e,o,u=t[0],f=t[1];return i.includes(u)?n({},r,{"+":n({},r["+"]||{},(o={},o[u]=f,o))}):n({},r,((e={})[u]=f,e))},{})}(e,o),f=u["+"],c=r(u,k);if(!f)return{_:E(c,!0),"+":void 0};if(!c||null==(i=Object.keys(c))||!i.length)return{_:E(c,!0),"+":f};var l=Object.keys(f).reduce(function(r,t){var e,i=o[t],u=i.on,f=i.fields,c=Array.isArray(u)?((e={})[u[0]]=1,e):void 0;return c||f?n({},r,c,f):r},c);return{_:E(l,!0),"+":f}}function T(n,r){if(!A(n)&&!A(r))return n||r?P(I(n),I(r)):{}}function P(r,t){void 0===r&&(r={}),void 0===t&&(t={});for(var e=n({},r),o=0,i=Object.entries(t||{});o<i.length;o++){var u=i[o],f=u[0],c=u[1],l=e[f];e[f]=a(l)&&a(c)?P(l,c):c}return e}function A(n){return void 0===n||!!n&&!a(n)}function I(n){return a(n)?h(function(n){return n[1]},n):{}}function F(r,t){var e,o,i,u;if(!a(t))return t;var f=O(),c=f?null==(e=t[f])?void 0:e[r]:t[r];if("number"!=typeof c)return t;if(Infinity===c)return t;var l=c-1;return n({},t,f?((u={})[f]=n({},t[f],((i={})[r]=l,i)),u):((o={})[r]=l,o))}var L=["fields","transform"],M=["_key","Coll","on","single","postFetch","limit"],N=["_key","Coll","on","single","postFetch","limit"];function S(t,e,o){void 0===e&&(e={}),void 0===o&&(o={});var u=i(),d=u.count,s=u.findList,m=u.getTransform,h=_(t),y=m(t),b=o.fields,w=o.transform,j=void 0===w?y:w,g=r(o,L),O=function(n){return l(j)?j(n):n},k=C(b,h),x=k._,T=k["+"],P=void 0===T?{}:T,A=Object.keys(P);return!h||null==A||!A.length||b&&!a(b)?p(s(t,e,n({},g,{fields:x,transform:null})),function(n){return n.map(O)}):p(s(t,e,n({},g,{fields:x,transform:null})),function(e){var i=A.reduce(function(r,t){var e,o=h[t];if(!o)return r;var i=f(o.on),u=n({},o,{_key:t});return n({},r,((e={})[i]=[].concat(r[i]||[],[u]),e))},{}),u=i.array,s=i.object,m=void 0===s?[]:s,y=i.function,w=void 0===y?[]:y;return p((void 0===u?[]:u).reduce(function(e,i){var u=i._key,s=i.Coll,m=i.on,h=i.single,y=i.postFetch,w=r(i,M);return p(e,function(r){var e,i,g=m[0],O=m[1],k=m[2],x=void 0===k?{}:k,T=c(g),A=T?r.flatMap(function(n){return n[g[0]]}):r.map(function(n){return n[g]}),I=c(O),L=n({},x,I?((e={})[O[0]]={$elemMatch:{$in:A}},e):((i={})[O]={$in:A},i)),M=s===t&&P[u]>1;return p(M&&d(t,L),function(t){var e,i=M&&!t,d=M?F(u,b):P[u],m=C(d,_(s)||{})._,k=!m||Object.keys(m).length<=0,x=a(d)&&!k&&"_id"!==O?n({},d,((e={})[O]=1,e)):d,A=n({},o,w,{fields:E(x),limit:void 0,transform:M?j:void 0});return p(i?[]:S(s,L,A),function(t){var e=I?{}:t.reduce(function(r,t){var e,o=v(O,t);return c(o)?o.reduce(function(r,e){var o;return n({},r,((o={})[e]=[].concat(r[e]||[],[t]),o))},r):n({},r,((e={})[o]=[].concat(r[o]||[],[t]),e))},{});return r.map(function(r){var o,i,c,a,d=[];I?d=t.filter(function(n){var t,e=n[O[0]]||[];return T?(t=e,(r[g[0]]||[]).some(function(n){return t.indexOf(n)>=0})):e.includes(r[g])}):T?(i="_id",c=(r[g[0]]||[]).flatMap(function(n){return e[n]||[]}),a=l(i)?i:"string"===f(i)?function(n){return n[i]}:function(n){return n},d=c.reduce(function(n,r){var t=a(r);return n.find(function(n){return a(n)===t})?n:[].concat(n,[r])},[])):d=e[r[g]]||[];var s=h?d[0]:d,v=l(y)?y(s,r):s;return n({},r,((o={})[u]=v,o))})})})})},e),function(n){return p(m.map(function(n){return R({Coll:t,join:n,fields:P[n._key],subSelector:n.on,options:g,parentFields:b})}),function(r){return p(n.map(function(n){var e=r.reduce(function(n,r){return r(n)},n);return p(w.reduce(function(r,e){var o=e.on;return p([r,R({Coll:t,join:e,fields:P[e._key],subSelector:l(o)?o(n):o,options:g,parentFields:b})],function(n){return(0,n[1])(n[0])})},e),function(n){return O(n)})}),function(n){return n})})})})}function J(r,t,e){return void 0===e&&(e={}),p(S(r,t,n({},e,{limit:1})),function(n){return n[0]})}function R(t){var e=t.Coll,o=t.join,u=o._key,f=o.Coll,c=o.single,a=o.postFetch,d=o.limit,s=r(o,N),v=t.fields,m=t.subSelector,h=t.options,y=t.parentFields,b=i(),w=f===e;return p(w&&(0,b.count)(e,m),function(r){var t=w&&(!v||!r),e=w?F(u,y):v,o=n({},h,s,{fields:E(e),limit:c?1:d||void 0});return p(t?[]:S(f,m,o),function(r){return function(t){var e,o=c?r[0]:r,i=l(a)?a(o,t):o;return n({},t,((e={})[u]=i,e))}})})}var U=["beforeInsert","beforeUpdate","beforeRemove","onInserted","onUpdated","onRemoved"],$=["onInserted","onUpdated","onRemoved"],D=new Map;function q(n,r){var t=D.get(n)||{};return r?t[r]:t}function z(n,r){var t=q(n,r);if(t)return function(n){if(void 0===n&&(n=[]),n.length){var r=n.reduce(function(n,r){return{fields:T(n.fields,r.fields),before:n.before||r.before}},{fields:null,before:void 0});return{before:r.before,fields:r.fields,fn:function(){var r=arguments;return p(n.map(function(n){return W.apply(void 0,[n].concat([].slice.call(r)))}))}}}}(t)}function W(n){void 0===n&&(n={});var r=[].slice.call(arguments,1),t=n.fn,e=n.onError,o=n.unless,i=n.when;if(l(t))try{if(null==o?void 0:o.apply(void 0,r))return;if(i&&!i.apply(void 0,r))return;return t.apply(void 0,r)}catch(r){if(!l(e))throw r;e(r,n)}}function B(n,r){var t;null==(t=console)||t.error("Error in '"+r.hookType+"' hook of '"+r.collName+"' collection:",n)}var G=["multi"],H=["multi"],K=["multi"],Q={__proto__:null,meteorAsync:{count:function(n,r,t){var e=n.rawCollection();return e.countDocuments?e.countDocuments(r):n.find(r,t).countAsync()},findList:function(n,r,t){return n.find(r,t).fetchAsync()},getName:function(n){return n._name||""},getTransform:function(n){return n._transform},insert:function(n,r){return n.insertAsync(r)},remove:function(n,r){return n.removeAsync(r)},update:function(r,t,e,o){return r.updateAsync(t,e,n({multi:!0},o))}},meteorSync:{count:function(n,r,t){return n.find(r,t).count()},findList:function(n,r,t){return n.find(r,t).fetch()},getName:function(n){return n._name||""},getTransform:function(n){return n._transform},insert:function(n,r){return n.insert(r)},remove:function(n,r){return n.remove(r)},update:function(r,t,e,o){return r.update(t,e,n({multi:!0},o))}},node:{count:function(n,r,t){return void 0===r&&(r={}),void 0===t&&(t={}),n.countDocuments(r||{},t)},findList:function(n,r,t){void 0===r&&(r={}),void 0===t&&(t={});var e=s({fields:"projection"},t||{});return n.find(r||{},e).toArray()},getName:function(n){return n.collectionName||""},getTransform:function(n){return"function"==typeof(null==n?void 0:n.transform)?n.transform:void 0},insert:function(n,r,t){return n.insertOne(r,t).then(function(n){return null==n?void 0:n.insertedId})},remove:function(n,t,e){void 0===t&&(t={}),void 0===e&&(e={});var o=e||{},i=o.multi,u=void 0===i||i,f=r(o,H);return(u?n.deleteMany(t||{},f):n.deleteOne(t||{},f)).then(function(n){var r;return null!=(r=null==n?void 0:n.deletedCount)?r:0})},update:function(n,t,e,o){void 0===t&&(t={}),void 0===e&&(e={}),void 0===o&&(o={});var i=o||{},u=i.multi,f=void 0===u||u,c=r(i,K);return(f?n.updateMany(t||{},e||{},c):n.updateOne(t||{},e||{},c)).then(function(n){var r,t;return null!=(r=null!=(t=null==n?void 0:n.modifiedCount)?t:null==n?void 0:n.upsertedCount)?r:0})}}};exports.count=function(n,r,t){return p((0,i().count)(n,r,t),function(n){return n})},exports.exists=function(n,r){return p(J(n,r,{fields:{_id:1}}),function(n){return!!n})},exports.fetchIds=function(r,t,e){return p(S(r,t,n({},e,{fields:{_id:1}})),function(n){return n.map(function(n){return n._id})})},exports.fetchList=S,exports.fetchOne=J,exports.flattenFields=x,exports.getJoinPrefix=O,exports.getJoins=_,exports.hook=function(r,t){Object.entries(t).forEach(function(t){var e=t[0],o=t[1];if(!c(o))throw new TypeError("'"+e+"' hooks must be an array");o.forEach(function(t){return function(r,t,e){var o;if(!U.includes(t))throw new TypeError("'"+t+"' is not a valid hook type");if(!l(null==e?void 0:e.fn))throw new TypeError("'hook' must be a function or contain a 'fn' key");var u=i().getName,f=q(r),c=f[t]||[],a=n({onError:$.includes(t)?B:void 0},e,{Coll:r,collName:u(r),hookType:t}),d=[].concat(c,[a]);D.set(r,n({},f,((o={})[t]=d,o)))}(r,e,t)})})},exports.insert=function(n,r){var t=i(),e=z(n,"beforeInsert");return p(l(null==e?void 0:e.fn)&&e.fn(r),function(){var e=z(n,"onInserted");return p(t.insert(n,r),function(r){if(!e)return r;var t=e.fields,o=e.fn,i=t?Object.keys(t):[];return p(1===i.length&&"_id"===i[0]?{_id:r}:J(n,{_id:r},{fields:t}),function(n){return y(function(){return o(n)},function(n){var r;return null==(r=console)?void 0:r.error("'onInserted' error:",n)}),r})})})},exports.join=function(r,t){t?(Object.entries(t).forEach(function(n){var r=n[0],t=n[1],e=t.on,o=t.fields;if(!t.Coll)throw new Error("Collection 'Coll' for '"+r+"' join is required.");if(!e)throw new Error("Join '"+r+"' has no 'on' condition specified.");var i=f(e);if(!b.includes(i))throw new Error("Join '"+r+"' has an unrecognized 'on' condition type of '"+i+"'. Should be one of '"+w+"'.");l(e)&&!o&&function(){var n;console&&console.warn&&(n=console).warn.apply(n,[].slice.call(arguments))}("Join '"+r+"' is defined with a function 'on', but no 'fields' are explicitly specified. This could lead to failed joins if the keys necessary for the join are not specified at query time.")}),j.set(r,n({},j.get(r),t))):j.set(r,void 0)},exports.protocols=Q,exports.remove=function(n,r){var t=i(),e=z(n,"beforeRemove"),o=z(n,"onRemoved"),u=function(){var n=[].slice.call(arguments).filter(function(n){return n});return n.length?n.reduce(function(n,r){return T(n,r.fields)},null):null}(e,o);return p(null===u?[]:S(n,r,{fields:u}),function(i){return p(l(null==e?void 0:e.fn)&&e.fn(i),function(){var e=t.remove(n,r);return e&&l(null==o?void 0:o.fn)?(y(function(){return i.forEach(function(n){return o.fn(n)})},function(n){var r;return null==(r=console)?void 0:r.error("'onRemoved' error:",n)}),e):e})})},exports.setJoinPrefix=function(n){g=n},exports.setProtocol=function(r){void 0===r&&(r={}),o=n({},e,r)},exports.update=function(t,e,o,u){var f=void 0===u?{}:u,c=f.multi,a=void 0===c||c,d=r(f,G),s=i(),v=z(t,"beforeUpdate"),m=z(t,"onUpdated"),h=n({multi:a},d),b=function(n,r){if(!n&&!r)return null;if(!r)return null==n?void 0:n.fields;var t=r.before?r.fields:{_id:1};return n?T(n.fields,t):t}(v,m);return p(null===b?[]:S(t,e,{fields:b,limit:a?void 0:1}),function(n){return p(l(null==v?void 0:v.fn)&&v.fn(n,o),function(){return p(s.update(t,e,o,h),function(r){if(!r||!l(null==m?void 0:m.fn))return r;var e=function(n){return void 0===n&&(n=[]),Object.fromEntries(n.map(function(n){return[n._id,n]}))}(n);return p(S(t,{_id:{$in:Object.keys(e)}},{fields:m.fields}),function(n){return y(function(){return n.forEach(function(n){m.fn(n,e[n._id])})},function(n){var r;return null==(r=console)?void 0:r.error("'onUpdated' error:",n)}),r})})})})};
1
+ function n(){return n=Object.assign?Object.assign.bind():function(n){for(var r=1;r<arguments.length;r++){var e=arguments[r];for(var t in e)({}).hasOwnProperty.call(e,t)&&(n[t]=e[t])}return n},n.apply(null,arguments)}function r(n,r){if(null==n)return{};var e={};for(var t in n)if({}.hasOwnProperty.call(n,t)){if(-1!==r.indexOf(t))continue;e[t]=n[t]}return e}function e(n){var r=function(n){if("object"!=typeof n||!n)return n;var r=n[Symbol.toPrimitive];if(void 0!==r){var e=r.call(n,"string");if("object"!=typeof e)return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(n)}(n);return"symbol"==typeof r?r:r+""}var t={count:function(){throw new Error("'count' method must be defined with 'setProtocol'.")},findList:function(){throw new Error("'findList' method must be defined with 'setProtocol'.")},getName:function(){return""},getTransform:function(){},insert:function(){throw new Error("'insert' method must be defined with 'setProtocol'.")},remove:function(){throw new Error("'remove' method must be defined with 'setProtocol'.")},update:function(){throw new Error("'update' method must be defined with 'setProtocol'.")}},o=t;function i(n){return n?"function"==typeof n?n(o):"object"==typeof n?n:o:o}var u=function(){},f=function(n){return{}.toString.call(n).split(" ")[1].slice(0,-1).toLowerCase()},c=function(n){return Array.isArray(n)},l=function(n){return"function"==typeof n},a=function(n){return n&&!c(n)&&"object"===f(n)};function d(n){return l(null==n?void 0:n.then)}function s(n,r){return p(function(r){var e=r[0];return[n[e]||e,r[1]]},r)}function v(n,r){var e=n.split("."),t=e[0],o=function(n,r){(null==r||r>n.length)&&(r=n.length);for(var e=0,t=Array(r);e<r;e++)t[e]=n[e];return t}(e).slice(1),i=r[t];if(o.length<1)return i;var u=o.join(".");return a(i)?v(u,i):c(i)?i.flatMap(function(n){var r=v(u,n);return c(r)?r:[r]}):i}function m(n,r){if(void 0===r&&(r=u),c(n)){var e=n;return e.some(d)?Promise.all(e).then(function(n){return r(n,!0)}):r(e,!1)}return d(n)?n.then(function(n){return r(n,!0)}):r(n,!1)}function p(n,r){if(void 0===r)return function(r){return p(n,r)};if(c(r))return r.map(n);if(!a(r))throw new TypeError("'map' only works on array or plain object");return Object.fromEntries(Object.entries(r).map(n))}function h(n,r){if(void 0===r)return function(r){return h(n,r)};if(c(r))return r.filter(n);if(!a(r))throw new TypeError("'filter' only works on array or plain object");return Object.fromEntries(Object.entries(r).filter(n))}function y(n,r){queueMicrotask(function(){try{var e=function(r,e){try{var t=Promise.resolve(n()).then(function(){})}catch(n){return e(n)}return t&&t.then?t.then(void 0,e):t}(0,function(n){l(r)&&r(n)});return Promise.resolve(e&&e.then?e.then(function(){}):void 0)}catch(n){return Promise.reject(n)}})}var b=["array","function","object"],w=b.join("', '"),g=new Map,j=null;function x(n){return g.get(n)||{}}function _(){return j}var E=["+"];function O(n,r){return void 0===r&&(r=!1),a(n)?r?P(n):n:n?void 0:{}}function P(r,e){var t;if(!r)return r;var o=Object.keys(r);return o.some(function(n){return n.startsWith("$")})?e?((t={})[e]=r,t):r:o.reduce(function(t,o){var i=o.indexOf(".");if(i>=0){var u=o.slice(0,i),f=r[u];if(f&&!a(f))return t}var c,l=r[o],d=e?[e,o].join("."):o;return a(l)?n({},t,P(l,d)):n({},t,((c={})[d]=!!l,c))},void 0)}function k(t,o){var i;if(void 0===o&&(o={}),!a(t))return{_:O(t)};var u=function(t,o){void 0===o&&(o={});var i=Object.keys(o),u=_();if(u){var f=t[u],c=r(t,[u].map(e));return n(f?{"+":h(function(n){return i.includes(n[0])},f)}:{"+":void 0},c)}return Object.entries(t).reduce(function(r,e){var t,o,u=e[0],f=e[1];return i.includes(u)?n({},r,{"+":n({},r["+"]||{},(o={},o[u]=f,o))}):n({},r,((t={})[u]=f,t))},{})}(t,o),f=u["+"],c=r(u,E);if(!f)return{_:O(c,!0),"+":void 0};if(!c||null==(i=Object.keys(c))||!i.length)return{_:O(c,!0),"+":f};var l=Object.keys(f).reduce(function(r,e){var t,i=o[e],u=i.on,f=i.fields,c=Array.isArray(u)?((t={})[u[0]]=1,t):void 0;return c||f?n({},r,c,f):r},c);return{_:O(l,!0),"+":f}}function C(n,r){if(!A(n)&&!A(r))return n||r?T(I(n),I(r)):{}}function T(r,e){void 0===r&&(r={}),void 0===e&&(e={});for(var t=n({},r),o=0,i=Object.entries(e||{});o<i.length;o++){var u=i[o],f=u[0],c=u[1],l=t[f];t[f]=a(l)&&a(c)?T(l,c):c}return t}function A(n){return void 0===n||!!n&&!a(n)}function I(n){return a(n)?h(function(n){return n[1]},n):{}}function N(r,e){var t,o,i,u;if(!a(e))return e;var f=_(),c=f?null==(t=e[f])?void 0:t[r]:e[r];if("number"!=typeof c)return e;if(Infinity===c)return e;var l=c-1;return n({},e,f?((u={})[f]=n({},e[f],((i={})[r]=l,i)),u):((o={})[r]=l,o))}var M=["fields","transform"],S=["_key","Coll","on","single","postFetch","limit"],F=["_key","Coll","on","single","postFetch","limit"];function L(e,t,o){void 0===t&&(t={}),void 0===o&&(o={});var u=i(),d=u.count,s=u.findList,p=u.getTransform,h=x(e),y=p(e),b=o.fields,w=o.transform,g=void 0===w?y:w,j=r(o,M),_=function(n){return l(g)?g(n):n},E=k(b,h),P=E._,C=E["+"],T=void 0===C?{}:C,A=Object.keys(T);return!h||null==A||!A.length||b&&!a(b)?m(s(e,t,n({},j,{fields:P,transform:null})),function(n){return n.map(_)}):m(s(e,t,n({},j,{fields:P,transform:null})),function(t){var i=A.reduce(function(r,e){var t,o=h[e];if(!o)return r;var i=f(o.on),u=n({},o,{_key:e});return n({},r,((t={})[i]=[].concat(r[i]||[],[u]),t))},{}),u=i.array,s=i.object,p=void 0===s?[]:s,y=i.function,w=void 0===y?[]:y;return m((void 0===u?[]:u).reduce(function(t,i){var u=i._key,s=i.Coll,p=i.on,h=i.single,y=i.postFetch,w=r(i,S);return m(t,function(r){var t,i,j=p[0],_=p[1],E=p[2],P=void 0===E?{}:E,C=c(j),A=C?r.flatMap(function(n){return n[j[0]]}):r.map(function(n){return n[j]}),I=c(_),M=n({},P,I?((t={})[_[0]]={$elemMatch:{$in:A}},t):((i={})[_]={$in:A},i)),S=s===e&&T[u]>1;return m(S&&d(e,M),function(e){var t,i=S&&!e,d=S?N(u,b):T[u],p=k(d,x(s)||{})._,E=!p||Object.keys(p).length<=0,P=a(d)&&!E&&"_id"!==_?n({},d,((t={})[_]=1,t)):d,A=n({},o,w,{fields:O(P),limit:void 0,transform:S?g:void 0});return m(i?[]:L(s,M,A),function(e){var t=I?{}:e.reduce(function(r,e){var t,o=v(_,e);return c(o)?o.reduce(function(r,t){var o;return n({},r,((o={})[t]=[].concat(r[t]||[],[e]),o))},r):n({},r,((t={})[o]=[].concat(r[o]||[],[e]),t))},{});return r.map(function(r){var o,i,c,a,d=[];I?d=e.filter(function(n){var e,t=n[_[0]]||[];return C?(e=t,(r[j[0]]||[]).some(function(n){return e.indexOf(n)>=0})):t.includes(r[j])}):C?(i="_id",c=(r[j[0]]||[]).flatMap(function(n){return t[n]||[]}),a=l(i)?i:"string"===f(i)?function(n){return n[i]}:function(n){return n},d=c.reduce(function(n,r){var e=a(r);return n.find(function(n){return a(n)===e})?n:[].concat(n,[r])},[])):d=t[r[j]]||[];var s=h?d[0]:d,v=l(y)?y(s,r):s;return n({},r,((o={})[u]=v,o))})})})})},t),function(n){return m(p.map(function(n){return R({Coll:e,join:n,fields:T[n._key],subSelector:n.on,options:j,parentFields:b})}),function(r){return m(n.map(function(n){var t=r.reduce(function(n,r){return r(n)},n);return m(w.reduce(function(r,t){var o=t.on;return m([r,R({Coll:e,join:t,fields:T[t._key],subSelector:l(o)?o(n):o,options:j,parentFields:b})],function(n){return(0,n[1])(n[0])})},t),function(n){return _(n)})}),function(n){return n})})})})}function J(r,e,t){return void 0===t&&(t={}),m(L(r,e,n({},t,{limit:1})),function(n){return n[0]})}function R(e){var t=e.Coll,o=e.join,u=o._key,f=o.Coll,c=o.single,a=o.postFetch,d=o.limit,s=r(o,F),v=e.fields,p=e.subSelector,h=e.options,y=e.parentFields,b=i(),w=f===t;return m(w&&(0,b.count)(t,p),function(r){var e=w&&(!v||!r),t=w?N(u,y):v,o=n({},h,s,{fields:O(t),limit:c?1:d||void 0});return m(e?[]:L(f,p,o),function(r){return function(e){var t,o=c?r[0]:r,i=l(a)?a(o,e):o;return n({},e,((t={})[u]=i,t))}})})}var U="drop",$="shift",z=!1,q=W({maxConcurrent:10,maxPending:250});function D(){return z=!0,q}function W(n){var r=function(n){try{if(d.size>=t)throw new Error("Max concurrent calls reached");var e=function(r,e){try{var t=function(r,e){try{var t=function(){d.add(n);var r=n.args;return Promise.resolve(n.fn.apply(void 0,void 0===r?[]:r)).then(function(){})}()}catch(n){return e(n)}return t&&t.then?t.then(void 0,e):t}(0,function(r){!function(n,r){var e=l(u)?u:console.error;Promise.resolve().then(function(){return e(n,r)}).catch(function(n){return console.error(n)})}(r,n)})}catch(n){return e(!0,n)}return t&&t.then?t.then(e.bind(null,!1),e.bind(null,!0)):e(!1,t)}(0,function(e,o){if(d.delete(n),function(){if(!(d.size>=t)){var n=a.shift();n&&r(n)}}(),e)throw o;return o});return Promise.resolve(e&&e.then?e.then(function(){}):void 0)}catch(n){return Promise.reject(n)}},e=n.maxConcurrent,t=void 0===e?10:e,o=n.maxPending,i=void 0===o?250:o,u=n.onError,f=n.onOverflow,c=void 0===f?B:f;!function(n){void 0===n&&(n={});var r=n.maxConcurrent,e=n.maxPending,t=n.onOverflow;if(!(Number.isFinite(r)&&Number.isInteger(r)&&r>=1))throw new TypeError("'maxConcurrent' must be a finite positive integer.");if(!(Infinity===e||Number.isInteger(e)&&e>=0))throw new TypeError("'maxPending' must be a positive integer or `Infinity`");if(!l(t)&&![U,$].includes(t))throw new TypeError("'onOverflow' must be either a function or one of '"+U+"' or '"+$+"'")}({maxConcurrent:t,maxPending:i,onError:u,onOverflow:c});var a=[],d=new Set;function s(n){d.size<t?r(n):a.length<i?a.push(n):function(n){c!==U&&(c===$?(a.shift(),a.length<i&&s(n)):l(c)?function(n){var r=[].concat(a,[n]),e=c([].concat(a),n);if(void 0!==e){if(!Array.isArray(e))throw new TypeError("'onOverflow' must return an array");var t=e.reduce(function(n,e){var t=e._id,o=r.find(function(n){return n._id===t});return o?n.includes(o)?n:[].concat(n,[o]):n},[]);a=t}}(n):console.error("Invalid 'onOverflow'"))}(n)}return{add:function(n){s({_id:Symbol(),fn:n,args:Array.from([].slice.call(arguments,1))})},clear:function(){a=[]}}}function B(){console.warn("'maxPending' limit reached. Call is dropped")}var G,H=function(n){void 0===n&&(n={});try{var r,e=[].slice.call(arguments,1),t=n.hookType,o=n.fn,i=n.onError,u=n.unless,f=n.when;return l(o)?Promise.resolve(function(n,i){try{var c=function(){function n(n){return r?n:Promise.resolve(o.apply(void 0,e))}if(!(null==u?void 0:u.apply(void 0,e))&&(!f||f.apply(void 0,e))){var i=function(){if(!Q.includes(t))return Promise.resolve(o.apply(void 0,e)).then(function(n){return r=1,n})}();return i&&i.then?i.then(n):n(i)}}()}catch(n){return i(n)}return c&&c.then?c.then(void 0,i):c}(0,function(r){if(!l(i))throw r;i(r,n)})):Promise.resolve()}catch(n){return Promise.reject(n)}},K=["beforeInsert","beforeUpdate","beforeRemove","onInserted","onUpdated","onRemoved"],Q=["onInserted","onUpdated","onRemoved"],V=new Map;function X(n,r){var e=V.get(n)||{};return r?e[r]:e}function Y(n,r){var e=X(n,r);if(e)return function(n,r){if(void 0===n&&(n=[]),void 0===r&&(r=!1),n.length){var e=function(n){return void 0===n&&(n=[]),n.reduce(function(n,r){return{fields:C(n.fields,r.fields),before:n.before||r.before}},{fields:null,before:void 0})}(n);return{before:e.before,fields:e.fields,fn:function(){var e=[].slice.call(arguments);if(!r)return m(n.map(function(n){return H.apply(void 0,[n].concat(e))}));n.forEach(function(n){return Z.apply(void 0,[n].concat(e))})}}}}(e,Q.includes(r))}function Z(n){void 0===n&&(n={});var r=null!=G?G:G||(G=D());r.add.apply(r,[H,n].concat([].slice.call(arguments,1)))}function nn(n,r){var e;null==(e=console)||e.error("Error in '"+r.hookType+"' hook of '"+r.collName+"' collection:",n)}var rn=["multi"],en=["multi"],tn=["multi"],on={__proto__:null,meteorAsync:{count:function(n,r,e){var t=n.rawCollection();return t.countDocuments?t.countDocuments(r):n.find(r,e).countAsync()},findList:function(n,r,e){return n.find(r,e).fetchAsync()},getName:function(n){return n._name||""},getTransform:function(n){return n._transform},insert:function(n,r){return n.insertAsync(r)},remove:function(n,r){return n.removeAsync(r)},update:function(r,e,t,o){return r.updateAsync(e,t,n({multi:!0},o))}},meteorSync:{count:function(n,r,e){return n.find(r,e).count()},findList:function(n,r,e){return n.find(r,e).fetch()},getName:function(n){return n._name||""},getTransform:function(n){return n._transform},insert:function(n,r){return n.insert(r)},remove:function(n,r){return n.remove(r)},update:function(r,e,t,o){return r.update(e,t,n({multi:!0},o))}},node:{count:function(n,r,e){return void 0===r&&(r={}),void 0===e&&(e={}),n.countDocuments(r||{},e)},findList:function(n,r,e){void 0===r&&(r={}),void 0===e&&(e={});var t=s({fields:"projection"},e||{});return n.find(r||{},t).toArray()},getName:function(n){return n.collectionName||""},getTransform:function(n){return"function"==typeof(null==n?void 0:n.transform)?n.transform:void 0},insert:function(n,r,e){return n.insertOne(r,e).then(function(n){return null==n?void 0:n.insertedId})},remove:function(n,e,t){void 0===e&&(e={}),void 0===t&&(t={});var o=t||{},i=o.multi,u=void 0===i||i,f=r(o,en);return(u?n.deleteMany(e||{},f):n.deleteOne(e||{},f)).then(function(n){var r;return null!=(r=null==n?void 0:n.deletedCount)?r:0})},update:function(n,e,t,o){void 0===e&&(e={}),void 0===t&&(t={}),void 0===o&&(o={});var i=o||{},u=i.multi,f=void 0===u||u,c=r(i,tn);return(f?n.updateMany(e||{},t||{},c):n.updateOne(e||{},t||{},c)).then(function(n){var r,e;return null!=(r=null!=(e=null==n?void 0:n.modifiedCount)?e:null==n?void 0:n.upsertedCount)?r:0})}}};exports.configurePool=function(n){if(void 0===n&&(n={}),z)throw new Error("'configurePool' must be called at startup before processing hooks");q=W(n)},exports.count=function(n,r,e){return m((0,i().count)(n,r,e),function(n){return n})},exports.exists=function(n,r){return m(J(n,r,{fields:{_id:1}}),function(n){return!!n})},exports.fetchIds=function(r,e,t){return m(L(r,e,n({},t,{fields:{_id:1}})),function(n){return n.map(function(n){return n._id})})},exports.fetchList=L,exports.fetchOne=J,exports.flattenFields=P,exports.getJoinPrefix=_,exports.getJoins=x,exports.hook=function(r,e){Object.entries(e).forEach(function(e){var t=e[0],o=e[1];if(!c(o))throw new TypeError("'"+t+"' hooks must be an array");o.forEach(function(e){return function(r,e,t){var o;if(!K.includes(e))throw new TypeError("'"+e+"' is not a valid hook type");if(!l(null==t?void 0:t.fn))throw new TypeError("'hook' must be a function or contain a 'fn' key");var u=i().getName,f=X(r),c=f[e]||[],a=n({onError:Q.includes(e)?nn:void 0},t,{Coll:r,collName:u(r),hookType:e}),d=[].concat(c,[a]);V.set(r,n({},f,((o={})[e]=d,o)))}(r,t,e)})})},exports.insert=function(n,r){var e=i(),t=Y(n,"beforeInsert");return m(l(null==t?void 0:t.fn)&&t.fn(r),function(){var t=Y(n,"onInserted");return m(e.insert(n,r),function(r){if(!t)return r;var e=t.fields,o=t.fn,i=e?Object.keys(e):[];return m(1===i.length&&"_id"===i[0]?{_id:r}:J(n,{_id:r},{fields:e}),function(n){return y(function(){return o(n)},function(n){var r;return null==(r=console)?void 0:r.error("'onInserted' error:",n)}),r})})})},exports.join=function(r,e){e?(Object.entries(e).forEach(function(n){var r=n[0],e=n[1],t=e.on,o=e.fields;if(!e.Coll)throw new Error("Collection 'Coll' for '"+r+"' join is required.");if(!t)throw new Error("Join '"+r+"' has no 'on' condition specified.");var i=f(t);if(!b.includes(i))throw new Error("Join '"+r+"' has an unrecognized 'on' condition type of '"+i+"'. Should be one of '"+w+"'.");l(t)&&!o&&function(){var n;console&&console.warn&&(n=console).warn.apply(n,[].slice.call(arguments))}("Join '"+r+"' is defined with a function 'on', but no 'fields' are explicitly specified. This could lead to failed joins if the keys necessary for the join are not specified at query time.")}),g.set(r,n({},g.get(r),e))):g.set(r,void 0)},exports.protocols=on,exports.remove=function(n,r){var e=i(),t=Y(n,"beforeRemove"),o=Y(n,"onRemoved"),u=function(){var n=[].slice.call(arguments).filter(function(n){return n});return n.length?n.reduce(function(n,r){return C(n,r.fields)},null):null}(t,o);return m(null===u?[]:L(n,r,{fields:u}),function(i){return m(l(null==t?void 0:t.fn)&&t.fn(i),function(){var t=e.remove(n,r);return t&&l(null==o?void 0:o.fn)?(y(function(){return i.forEach(function(n){return o.fn(n)})},function(n){var r;return null==(r=console)?void 0:r.error("'onRemoved' error:",n)}),t):t})})},exports.setJoinPrefix=function(n){j=n},exports.setProtocol=function(r){void 0===r&&(r={}),o=n({},t,r)},exports.update=function(e,t,o,u){var f=void 0===u?{}:u,c=f.multi,a=void 0===c||c,d=r(f,rn),s=i(),v=Y(e,"beforeUpdate"),p=Y(e,"onUpdated"),h=n({multi:a},d),b=function(n,r){if(!n&&!r)return null;if(!r)return null==n?void 0:n.fields;var e=r.before?r.fields:{_id:1};return n?C(n.fields,e):e}(v,p);return m(null===b?[]:L(e,t,{fields:b,limit:a?void 0:1}),function(n){return m(l(null==v?void 0:v.fn)&&v.fn(n,o),function(){return m(s.update(e,t,o,h),function(r){if(!r||!l(null==p?void 0:p.fn))return r;var t=function(n){return void 0===n&&(n=[]),Object.fromEntries(n.map(function(n){return[n._id,n]}))}(n);return m(L(e,{_id:{$in:Object.keys(t)}},{fields:p.fields}),function(n){return y(function(){return n.forEach(function(n){p.fn(n,t[n._id])})},function(n){var r;return null==(r=console)?void 0:r.error("'onUpdated' error:",n)}),r})})})})};
2
2
  //# sourceMappingURL=coll-fns.cjs.map