@verdant-web/store 5.2.0 → 5.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/dist/bundle/index.js +1 -1
- package/dist/bundle/index.js.map +2 -2
- package/dist/esm/sync/PresenceManager.js +0 -1
- package/dist/esm/sync/PresenceManager.js.map +1 -1
- package/dist/esm/sync/WebSocketSync.js +0 -1
- package/dist/esm/sync/WebSocketSync.js.map +1 -1
- package/package.json +2 -2
- package/src/sync/PresenceManager.ts +0 -1
- package/src/sync/WebSocketSync.ts +0 -1
package/dist/bundle/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../node_modules/.pnpm/object-hash@3.0.0/node_modules/object-hash/dist/object_hash.js", "../../../../node_modules/.pnpm/cuid@2.1.8/node_modules/cuid/lib/pad.js", "../../../../node_modules/.pnpm/cuid@2.1.8/node_modules/cuid/lib/fingerprint.browser.js", "../../../../node_modules/.pnpm/cuid@2.1.8/node_modules/cuid/lib/getRandomValue.browser.js", "../../../../node_modules/.pnpm/cuid@2.1.8/node_modules/cuid/index.js", "../../../../node_modules/.pnpm/tslib@2.6.2/node_modules/tslib/tslib.es6.mjs", "../../../../node_modules/.pnpm/weak-event@2.0.5/node_modules/weak-event/dist/typed-event-interfaces.js", "../../../../node_modules/.pnpm/weak-event@2.0.5/node_modules/weak-event/src/base-event/typed-event-functional.ts", "../../../../node_modules/.pnpm/weak-event@2.0.5/node_modules/weak-event/src/base-event/base-typed-event.ts", "../../../../node_modules/.pnpm/weak-event@2.0.5/node_modules/weak-event/src/base-event/index.ts", "../../../../node_modules/.pnpm/weak-event@2.0.5/node_modules/weak-event/src/weak-event/errors.ts", "../../../../node_modules/.pnpm/weak-event@2.0.5/node_modules/weak-event/src/weak-event/weak-event-finalization.ts", "../../../../node_modules/.pnpm/weak-event@2.0.5/node_modules/weak-event/src/weak-event/weak-event.ts", "../../../../node_modules/.pnpm/weak-event@2.0.5/node_modules/weak-event/src/weak-event/index.ts", "../../../../node_modules/.pnpm/weak-event@2.0.5/node_modules/weak-event/src/index.ts", "../../src/index.ts", "../../../common/src/authz.ts", "../../../common/src/batching.ts", "../../../common/src/error.ts", "../../../../node_modules/.pnpm/uuid@8.3.2/node_modules/uuid/dist/esm-browser/rng.js", "../../../../node_modules/.pnpm/uuid@8.3.2/node_modules/uuid/dist/esm-browser/regex.js", "../../../../node_modules/.pnpm/uuid@8.3.2/node_modules/uuid/dist/esm-browser/validate.js", "../../../../node_modules/.pnpm/uuid@8.3.2/node_modules/uuid/dist/esm-browser/stringify.js", "../../../../node_modules/.pnpm/uuid@8.3.2/node_modules/uuid/dist/esm-browser/v4.js", "../../../common/src/utils.ts", "../../../common/src/files.ts", "../../../common/src/refs.ts", "../../../common/src/operation.ts", "../../../common/src/oids.ts", "../../../common/src/oidsLegacy.ts", "../../../common/src/patch.ts", "../../../common/src/diffing.ts", "../../../common/src/EventSubscriber.ts", "../../../common/src/indexes.ts", "../../../common/src/memo.ts", "../../../common/src/migration.ts", "../../../common/src/presence.ts", "../../../common/src/replica.ts", "../../../common/src/schema/fieldHelpers.ts", "../../../common/src/schema/index.ts", "../../../common/src/schema/indexFilters.ts", "../../../common/src/schema/fields.ts", "../../../common/src/schema/validation.ts", "../../../common/src/schema/children.ts", "../../../common/src/timestamp.ts", "../../../common/src/undo.ts", "../../src/FakeWeakRef.ts", "../../src/UndoHistory.ts", "../../src/logger.ts", "../../src/utils/Disposable.ts", "../../src/persistence/idb/util.ts", "../../src/persistence/idb/IdbService.ts", "../../src/persistence/idb/files/IdbPersistenceFileDb.ts", "../../src/persistence/idb/metadata/IdbMetadataDb.ts", "../../src/persistence/idb/metadata/openMetadataDatabase.ts", "../../src/persistence/idb/queries/ranges.ts", "../../src/persistence/idb/queries/IdbDocumentDb.ts", "../../src/persistence/idb/queries/migration/db.ts", "../../src/persistence/idb/idbPersistence.ts", "../../src/context/ShutdownHandler.ts", "../../src/utils/wip.ts", "../../src/persistence/migration/engine.ts", "../../src/persistence/migration/finalize.ts", "../../src/persistence/migration/paths.ts", "../../src/persistence/migration/migrate.ts", "../../src/persistence/PersistenceFiles.ts", "../../src/persistence/PersistenceMetadata.ts", "../../src/persistence/MessageCreator.ts", "../../src/persistence/PersistenceRebaser.ts", "../../src/persistence/PersistenceQueries.ts", "../../src/persistence/persistence.ts", "../../src/context/Time.ts", "../../src/context/context.ts", "../../src/entities/DocumentManager.ts", "../../src/entities/EntityStore.ts", "../../src/files/utils.ts", "../../src/files/EntityFile.ts", "../../src/entities/EntityCache.ts", "../../src/entities/entityFieldSubscriber.ts", "../../src/entities/Entity.ts", "../../src/entities/EntityMetadata.ts", "../../src/entities/OperationBatcher.ts", "../../src/files/FileManager.ts", "../../src/queries/utils.ts", "../../src/queries/BaseQuery.ts", "../../src/queries/GetQuery.ts", "../../src/queries/FindOneQuery.ts", "../../src/queries/FindPageQuery.ts", "../../src/queries/FindInfiniteQuery.ts", "../../src/queries/FindAllQuery.ts", "../../src/queries/CollectionQueries.ts", "../../src/queries/QueryCache.ts", "../../src/sync/background.ts", "../../src/sync/FileSync.ts", "../../src/sync/PresenceManager.ts", "../../src/sync/Heartbeat.ts", "../../src/sync/PushPullSync.ts", "../../../../node_modules/.pnpm/jwt-decode@3.1.2/node_modules/jwt-decode/lib/atob.js", "../../../../node_modules/.pnpm/jwt-decode@3.1.2/node_modules/jwt-decode/lib/base64_url_decode.js", "../../../../node_modules/.pnpm/jwt-decode@3.1.2/node_modules/jwt-decode/lib/index.js", "../../src/sync/ServerSyncEndpointProvider.ts", "../../src/BackoffScheduler.ts", "../../src/sync/WebSocketSync.ts", "../../src/sync/Sync.ts", "../../src/utils/versions.ts", "../../src/client/Client.ts", "../../src/authorization.ts", "../../src/sync/cliSync.ts", "../../src/utils/id.ts", "../../src/vanilla.ts"],
|
|
4
|
-
"sourcesContent": ["!function(e){var t;\"object\"==typeof exports?module.exports=e():\"function\"==typeof define&&define.amd?define(e):(\"undefined\"!=typeof window?t=window:\"undefined\"!=typeof global?t=global:\"undefined\"!=typeof self&&(t=self),t.objectHash=e())}(function(){return function r(o,i,u){function s(n,e){if(!i[n]){if(!o[n]){var t=\"function\"==typeof require&&require;if(!e&&t)return t(n,!0);if(a)return a(n,!0);throw new Error(\"Cannot find module '\"+n+\"'\")}e=i[n]={exports:{}};o[n][0].call(e.exports,function(e){var t=o[n][1][e];return s(t||e)},e,e.exports,r,o,i,u)}return i[n].exports}for(var a=\"function\"==typeof require&&require,e=0;e<u.length;e++)s(u[e]);return s}({1:[function(w,b,m){!function(e,n,s,c,d,h,p,g,y){\"use strict\";var r=w(\"crypto\");function t(e,t){t=u(e,t);var n;return void 0===(n=\"passthrough\"!==t.algorithm?r.createHash(t.algorithm):new l).write&&(n.write=n.update,n.end=n.update),f(t,n).dispatch(e),n.update||n.end(\"\"),n.digest?n.digest(\"buffer\"===t.encoding?void 0:t.encoding):(e=n.read(),\"buffer\"!==t.encoding?e.toString(t.encoding):e)}(m=b.exports=t).sha1=function(e){return t(e)},m.keys=function(e){return t(e,{excludeValues:!0,algorithm:\"sha1\",encoding:\"hex\"})},m.MD5=function(e){return t(e,{algorithm:\"md5\",encoding:\"hex\"})},m.keysMD5=function(e){return t(e,{algorithm:\"md5\",encoding:\"hex\",excludeValues:!0})};var o=r.getHashes?r.getHashes().slice():[\"sha1\",\"md5\"],i=(o.push(\"passthrough\"),[\"buffer\",\"hex\",\"binary\",\"base64\"]);function u(e,t){var n={};if(n.algorithm=(t=t||{}).algorithm||\"sha1\",n.encoding=t.encoding||\"hex\",n.excludeValues=!!t.excludeValues,n.algorithm=n.algorithm.toLowerCase(),n.encoding=n.encoding.toLowerCase(),n.ignoreUnknown=!0===t.ignoreUnknown,n.respectType=!1!==t.respectType,n.respectFunctionNames=!1!==t.respectFunctionNames,n.respectFunctionProperties=!1!==t.respectFunctionProperties,n.unorderedArrays=!0===t.unorderedArrays,n.unorderedSets=!1!==t.unorderedSets,n.unorderedObjects=!1!==t.unorderedObjects,n.replacer=t.replacer||void 0,n.excludeKeys=t.excludeKeys||void 0,void 0===e)throw new Error(\"Object argument required.\");for(var r=0;r<o.length;++r)o[r].toLowerCase()===n.algorithm.toLowerCase()&&(n.algorithm=o[r]);if(-1===o.indexOf(n.algorithm))throw new Error('Algorithm \"'+n.algorithm+'\" not supported. supported values: '+o.join(\", \"));if(-1===i.indexOf(n.encoding)&&\"passthrough\"!==n.algorithm)throw new Error('Encoding \"'+n.encoding+'\" not supported. supported values: '+i.join(\", \"));return n}function a(e){if(\"function\"==typeof e)return null!=/^function\\s+\\w*\\s*\\(\\s*\\)\\s*{\\s+\\[native code\\]\\s+}$/i.exec(Function.prototype.toString.call(e))}function f(o,t,i){i=i||[];function u(e){return t.update?t.update(e,\"utf8\"):t.write(e,\"utf8\")}return{dispatch:function(e){return this[\"_\"+(null===(e=o.replacer?o.replacer(e):e)?\"null\":typeof e)](e)},_object:function(t){var n,e=Object.prototype.toString.call(t),r=/\\[object (.*)\\]/i.exec(e);r=(r=r?r[1]:\"unknown:[\"+e+\"]\").toLowerCase();if(0<=(e=i.indexOf(t)))return this.dispatch(\"[CIRCULAR:\"+e+\"]\");if(i.push(t),void 0!==s&&s.isBuffer&&s.isBuffer(t))return u(\"buffer:\"),u(t);if(\"object\"===r||\"function\"===r||\"asyncfunction\"===r)return e=Object.keys(t),o.unorderedObjects&&(e=e.sort()),!1===o.respectType||a(t)||e.splice(0,0,\"prototype\",\"__proto__\",\"constructor\"),o.excludeKeys&&(e=e.filter(function(e){return!o.excludeKeys(e)})),u(\"object:\"+e.length+\":\"),n=this,e.forEach(function(e){n.dispatch(e),u(\":\"),o.excludeValues||n.dispatch(t[e]),u(\",\")});if(!this[\"_\"+r]){if(o.ignoreUnknown)return u(\"[\"+r+\"]\");throw new Error('Unknown object type \"'+r+'\"')}this[\"_\"+r](t)},_array:function(e,t){t=void 0!==t?t:!1!==o.unorderedArrays;var n=this;if(u(\"array:\"+e.length+\":\"),!t||e.length<=1)return e.forEach(function(e){return n.dispatch(e)});var r=[],t=e.map(function(e){var t=new l,n=i.slice();return f(o,t,n).dispatch(e),r=r.concat(n.slice(i.length)),t.read().toString()});return i=i.concat(r),t.sort(),this._array(t,!1)},_date:function(e){return u(\"date:\"+e.toJSON())},_symbol:function(e){return u(\"symbol:\"+e.toString())},_error:function(e){return u(\"error:\"+e.toString())},_boolean:function(e){return u(\"bool:\"+e.toString())},_string:function(e){u(\"string:\"+e.length+\":\"),u(e.toString())},_function:function(e){u(\"fn:\"),a(e)?this.dispatch(\"[native]\"):this.dispatch(e.toString()),!1!==o.respectFunctionNames&&this.dispatch(\"function-name:\"+String(e.name)),o.respectFunctionProperties&&this._object(e)},_number:function(e){return u(\"number:\"+e.toString())},_xml:function(e){return u(\"xml:\"+e.toString())},_null:function(){return u(\"Null\")},_undefined:function(){return u(\"Undefined\")},_regexp:function(e){return u(\"regex:\"+e.toString())},_uint8array:function(e){return u(\"uint8array:\"),this.dispatch(Array.prototype.slice.call(e))},_uint8clampedarray:function(e){return u(\"uint8clampedarray:\"),this.dispatch(Array.prototype.slice.call(e))},_int8array:function(e){return u(\"int8array:\"),this.dispatch(Array.prototype.slice.call(e))},_uint16array:function(e){return u(\"uint16array:\"),this.dispatch(Array.prototype.slice.call(e))},_int16array:function(e){return u(\"int16array:\"),this.dispatch(Array.prototype.slice.call(e))},_uint32array:function(e){return u(\"uint32array:\"),this.dispatch(Array.prototype.slice.call(e))},_int32array:function(e){return u(\"int32array:\"),this.dispatch(Array.prototype.slice.call(e))},_float32array:function(e){return u(\"float32array:\"),this.dispatch(Array.prototype.slice.call(e))},_float64array:function(e){return u(\"float64array:\"),this.dispatch(Array.prototype.slice.call(e))},_arraybuffer:function(e){return u(\"arraybuffer:\"),this.dispatch(new Uint8Array(e))},_url:function(e){return u(\"url:\"+e.toString())},_map:function(e){u(\"map:\");e=Array.from(e);return this._array(e,!1!==o.unorderedSets)},_set:function(e){u(\"set:\");e=Array.from(e);return this._array(e,!1!==o.unorderedSets)},_file:function(e){return u(\"file:\"),this.dispatch([e.name,e.size,e.type,e.lastModfied])},_blob:function(){if(o.ignoreUnknown)return u(\"[blob]\");throw Error('Hashing Blob objects is currently not supported\\n(see https://github.com/puleos/object-hash/issues/26)\\nUse \"options.replacer\" or \"options.ignoreUnknown\"\\n')},_domwindow:function(){return u(\"domwindow\")},_bigint:function(e){return u(\"bigint:\"+e.toString())},_process:function(){return u(\"process\")},_timer:function(){return u(\"timer\")},_pipe:function(){return u(\"pipe\")},_tcp:function(){return u(\"tcp\")},_udp:function(){return u(\"udp\")},_tty:function(){return u(\"tty\")},_statwatcher:function(){return u(\"statwatcher\")},_securecontext:function(){return u(\"securecontext\")},_connection:function(){return u(\"connection\")},_zlib:function(){return u(\"zlib\")},_context:function(){return u(\"context\")},_nodescript:function(){return u(\"nodescript\")},_httpparser:function(){return u(\"httpparser\")},_dataview:function(){return u(\"dataview\")},_signal:function(){return u(\"signal\")},_fsevent:function(){return u(\"fsevent\")},_tlswrap:function(){return u(\"tlswrap\")}}}function l(){return{buf:\"\",write:function(e){this.buf+=e},end:function(e){this.buf+=e},read:function(){return this.buf}}}m.writeToStream=function(e,t,n){return void 0===n&&(n=t,t={}),f(t=u(e,t),n).dispatch(e)}}.call(this,w(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},w(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/fake_9a5aa49d.js\",\"/\")},{buffer:3,crypto:5,lYpoI2:11}],2:[function(e,t,f){!function(e,t,n,r,o,i,u,s,a){!function(e){\"use strict\";var a=\"undefined\"!=typeof Uint8Array?Uint8Array:Array,t=\"+\".charCodeAt(0),n=\"/\".charCodeAt(0),r=\"0\".charCodeAt(0),o=\"a\".charCodeAt(0),i=\"A\".charCodeAt(0),u=\"-\".charCodeAt(0),s=\"_\".charCodeAt(0);function f(e){e=e.charCodeAt(0);return e===t||e===u?62:e===n||e===s?63:e<r?-1:e<r+10?e-r+26+26:e<i+26?e-i:e<o+26?e-o+26:void 0}e.toByteArray=function(e){var t,n;if(0<e.length%4)throw new Error(\"Invalid string. Length must be a multiple of 4\");var r=e.length,r=\"=\"===e.charAt(r-2)?2:\"=\"===e.charAt(r-1)?1:0,o=new a(3*e.length/4-r),i=0<r?e.length-4:e.length,u=0;function s(e){o[u++]=e}for(t=0;t<i;t+=4,0)s((16711680&(n=f(e.charAt(t))<<18|f(e.charAt(t+1))<<12|f(e.charAt(t+2))<<6|f(e.charAt(t+3))))>>16),s((65280&n)>>8),s(255&n);return 2==r?s(255&(n=f(e.charAt(t))<<2|f(e.charAt(t+1))>>4)):1==r&&(s((n=f(e.charAt(t))<<10|f(e.charAt(t+1))<<4|f(e.charAt(t+2))>>2)>>8&255),s(255&n)),o},e.fromByteArray=function(e){var t,n,r,o,i=e.length%3,u=\"\";function s(e){return\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\".charAt(e)}for(t=0,r=e.length-i;t<r;t+=3)n=(e[t]<<16)+(e[t+1]<<8)+e[t+2],u+=s((o=n)>>18&63)+s(o>>12&63)+s(o>>6&63)+s(63&o);switch(i){case 1:u=(u+=s((n=e[e.length-1])>>2))+s(n<<4&63)+\"==\";break;case 2:u=(u=(u+=s((n=(e[e.length-2]<<8)+e[e.length-1])>>10))+s(n>>4&63))+s(n<<2&63)+\"=\"}return u}}(void 0===f?this.base64js={}:f)}.call(this,e(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},e(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/base64-js/lib/b64.js\",\"/node_modules/gulp-browserify/node_modules/base64-js/lib\")},{buffer:3,lYpoI2:11}],3:[function(O,e,H){!function(e,n,f,r,h,p,g,y,w){var a=O(\"base64-js\"),i=O(\"ieee754\");function f(e,t,n){if(!(this instanceof f))return new f(e,t,n);var r,o,i,u,s=typeof e;if(\"base64\"===t&&\"string\"==s)for(e=(u=e).trim?u.trim():u.replace(/^\\s+|\\s+$/g,\"\");e.length%4!=0;)e+=\"=\";if(\"number\"==s)r=j(e);else if(\"string\"==s)r=f.byteLength(e,t);else{if(\"object\"!=s)throw new Error(\"First argument needs to be a number, array or string.\");r=j(e.length)}if(f._useTypedArrays?o=f._augment(new Uint8Array(r)):((o=this).length=r,o._isBuffer=!0),f._useTypedArrays&&\"number\"==typeof e.byteLength)o._set(e);else if(C(u=e)||f.isBuffer(u)||u&&\"object\"==typeof u&&\"number\"==typeof u.length)for(i=0;i<r;i++)f.isBuffer(e)?o[i]=e.readUInt8(i):o[i]=e[i];else if(\"string\"==s)o.write(e,0,t);else if(\"number\"==s&&!f._useTypedArrays&&!n)for(i=0;i<r;i++)o[i]=0;return o}function b(e,t,n,r){return f._charsWritten=c(function(e){for(var t=[],n=0;n<e.length;n++)t.push(255&e.charCodeAt(n));return t}(t),e,n,r)}function m(e,t,n,r){return f._charsWritten=c(function(e){for(var t,n,r=[],o=0;o<e.length;o++)n=e.charCodeAt(o),t=n>>8,n=n%256,r.push(n),r.push(t);return r}(t),e,n,r)}function v(e,t,n){var r=\"\";n=Math.min(e.length,n);for(var o=t;o<n;o++)r+=String.fromCharCode(e[o]);return r}function o(e,t,n,r){r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(null!=t,\"missing offset\"),d(t+1<e.length,\"Trying to read beyond buffer length\"));var o,r=e.length;if(!(r<=t))return n?(o=e[t],t+1<r&&(o|=e[t+1]<<8)):(o=e[t]<<8,t+1<r&&(o|=e[t+1])),o}function u(e,t,n,r){r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(null!=t,\"missing offset\"),d(t+3<e.length,\"Trying to read beyond buffer length\"));var o,r=e.length;if(!(r<=t))return n?(t+2<r&&(o=e[t+2]<<16),t+1<r&&(o|=e[t+1]<<8),o|=e[t],t+3<r&&(o+=e[t+3]<<24>>>0)):(t+1<r&&(o=e[t+1]<<16),t+2<r&&(o|=e[t+2]<<8),t+3<r&&(o|=e[t+3]),o+=e[t]<<24>>>0),o}function _(e,t,n,r){if(r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(null!=t,\"missing offset\"),d(t+1<e.length,\"Trying to read beyond buffer length\")),!(e.length<=t))return r=o(e,t,n,!0),32768&r?-1*(65535-r+1):r}function E(e,t,n,r){if(r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(null!=t,\"missing offset\"),d(t+3<e.length,\"Trying to read beyond buffer length\")),!(e.length<=t))return r=u(e,t,n,!0),2147483648&r?-1*(4294967295-r+1):r}function I(e,t,n,r){return r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(t+3<e.length,\"Trying to read beyond buffer length\")),i.read(e,t,n,23,4)}function A(e,t,n,r){return r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(t+7<e.length,\"Trying to read beyond buffer length\")),i.read(e,t,n,52,8)}function s(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+1<e.length,\"trying to write beyond buffer length\"),Y(t,65535));o=e.length;if(!(o<=n))for(var i=0,u=Math.min(o-n,2);i<u;i++)e[n+i]=(t&255<<8*(r?i:1-i))>>>8*(r?i:1-i)}function l(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+3<e.length,\"trying to write beyond buffer length\"),Y(t,4294967295));o=e.length;if(!(o<=n))for(var i=0,u=Math.min(o-n,4);i<u;i++)e[n+i]=t>>>8*(r?i:3-i)&255}function B(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+1<e.length,\"Trying to write beyond buffer length\"),F(t,32767,-32768)),e.length<=n||s(e,0<=t?t:65535+t+1,n,r,o)}function L(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+3<e.length,\"Trying to write beyond buffer length\"),F(t,2147483647,-2147483648)),e.length<=n||l(e,0<=t?t:4294967295+t+1,n,r,o)}function U(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+3<e.length,\"Trying to write beyond buffer length\"),D(t,34028234663852886e22,-34028234663852886e22)),e.length<=n||i.write(e,t,n,r,23,4)}function x(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+7<e.length,\"Trying to write beyond buffer length\"),D(t,17976931348623157e292,-17976931348623157e292)),e.length<=n||i.write(e,t,n,r,52,8)}H.Buffer=f,H.SlowBuffer=f,H.INSPECT_MAX_BYTES=50,f.poolSize=8192,f._useTypedArrays=function(){try{var e=new ArrayBuffer(0),t=new Uint8Array(e);return t.foo=function(){return 42},42===t.foo()&&\"function\"==typeof t.subarray}catch(e){return!1}}(),f.isEncoding=function(e){switch(String(e).toLowerCase()){case\"hex\":case\"utf8\":case\"utf-8\":case\"ascii\":case\"binary\":case\"base64\":case\"raw\":case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":return!0;default:return!1}},f.isBuffer=function(e){return!(null==e||!e._isBuffer)},f.byteLength=function(e,t){var n;switch(e+=\"\",t||\"utf8\"){case\"hex\":n=e.length/2;break;case\"utf8\":case\"utf-8\":n=T(e).length;break;case\"ascii\":case\"binary\":case\"raw\":n=e.length;break;case\"base64\":n=M(e).length;break;case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":n=2*e.length;break;default:throw new Error(\"Unknown encoding\")}return n},f.concat=function(e,t){if(d(C(e),\"Usage: Buffer.concat(list, [totalLength])\\nlist should be an Array.\"),0===e.length)return new f(0);if(1===e.length)return e[0];if(\"number\"!=typeof t)for(o=t=0;o<e.length;o++)t+=e[o].length;for(var n=new f(t),r=0,o=0;o<e.length;o++){var i=e[o];i.copy(n,r),r+=i.length}return n},f.prototype.write=function(e,t,n,r){isFinite(t)?isFinite(n)||(r=n,n=void 0):(a=r,r=t,t=n,n=a),t=Number(t)||0;var o,i,u,s,a=this.length-t;switch((!n||a<(n=Number(n)))&&(n=a),r=String(r||\"utf8\").toLowerCase()){case\"hex\":o=function(e,t,n,r){n=Number(n)||0;var o=e.length-n;(!r||o<(r=Number(r)))&&(r=o),d((o=t.length)%2==0,\"Invalid hex string\"),o/2<r&&(r=o/2);for(var i=0;i<r;i++){var u=parseInt(t.substr(2*i,2),16);d(!isNaN(u),\"Invalid hex string\"),e[n+i]=u}return f._charsWritten=2*i,i}(this,e,t,n);break;case\"utf8\":case\"utf-8\":i=this,u=t,s=n,o=f._charsWritten=c(T(e),i,u,s);break;case\"ascii\":case\"binary\":o=b(this,e,t,n);break;case\"base64\":i=this,u=t,s=n,o=f._charsWritten=c(M(e),i,u,s);break;case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":o=m(this,e,t,n);break;default:throw new Error(\"Unknown encoding\")}return o},f.prototype.toString=function(e,t,n){var r,o,i,u,s=this;if(e=String(e||\"utf8\").toLowerCase(),t=Number(t)||0,(n=void 0!==n?Number(n):s.length)===t)return\"\";switch(e){case\"hex\":r=function(e,t,n){var r=e.length;(!t||t<0)&&(t=0);(!n||n<0||r<n)&&(n=r);for(var o=\"\",i=t;i<n;i++)o+=k(e[i]);return o}(s,t,n);break;case\"utf8\":case\"utf-8\":r=function(e,t,n){var r=\"\",o=\"\";n=Math.min(e.length,n);for(var i=t;i<n;i++)e[i]<=127?(r+=N(o)+String.fromCharCode(e[i]),o=\"\"):o+=\"%\"+e[i].toString(16);return r+N(o)}(s,t,n);break;case\"ascii\":case\"binary\":r=v(s,t,n);break;case\"base64\":o=s,u=n,r=0===(i=t)&&u===o.length?a.fromByteArray(o):a.fromByteArray(o.slice(i,u));break;case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":r=function(e,t,n){for(var r=e.slice(t,n),o=\"\",i=0;i<r.length;i+=2)o+=String.fromCharCode(r[i]+256*r[i+1]);return o}(s,t,n);break;default:throw new Error(\"Unknown encoding\")}return r},f.prototype.toJSON=function(){return{type:\"Buffer\",data:Array.prototype.slice.call(this._arr||this,0)}},f.prototype.copy=function(e,t,n,r){if(t=t||0,(r=r||0===r?r:this.length)!==(n=n||0)&&0!==e.length&&0!==this.length){d(n<=r,\"sourceEnd < sourceStart\"),d(0<=t&&t<e.length,\"targetStart out of bounds\"),d(0<=n&&n<this.length,\"sourceStart out of bounds\"),d(0<=r&&r<=this.length,\"sourceEnd out of bounds\"),r>this.length&&(r=this.length);var o=(r=e.length-t<r-n?e.length-t+n:r)-n;if(o<100||!f._useTypedArrays)for(var i=0;i<o;i++)e[i+t]=this[i+n];else e._set(this.subarray(n,n+o),t)}},f.prototype.slice=function(e,t){var n=this.length;if(e=S(e,n,0),t=S(t,n,n),f._useTypedArrays)return f._augment(this.subarray(e,t));for(var r=t-e,o=new f(r,void 0,!0),i=0;i<r;i++)o[i]=this[i+e];return o},f.prototype.get=function(e){return console.log(\".get() is deprecated. Access using array indexes instead.\"),this.readUInt8(e)},f.prototype.set=function(e,t){return console.log(\".set() is deprecated. Access using array indexes instead.\"),this.writeUInt8(e,t)},f.prototype.readUInt8=function(e,t){if(t||(d(null!=e,\"missing offset\"),d(e<this.length,\"Trying to read beyond buffer length\")),!(e>=this.length))return this[e]},f.prototype.readUInt16LE=function(e,t){return o(this,e,!0,t)},f.prototype.readUInt16BE=function(e,t){return o(this,e,!1,t)},f.prototype.readUInt32LE=function(e,t){return u(this,e,!0,t)},f.prototype.readUInt32BE=function(e,t){return u(this,e,!1,t)},f.prototype.readInt8=function(e,t){if(t||(d(null!=e,\"missing offset\"),d(e<this.length,\"Trying to read beyond buffer length\")),!(e>=this.length))return 128&this[e]?-1*(255-this[e]+1):this[e]},f.prototype.readInt16LE=function(e,t){return _(this,e,!0,t)},f.prototype.readInt16BE=function(e,t){return _(this,e,!1,t)},f.prototype.readInt32LE=function(e,t){return E(this,e,!0,t)},f.prototype.readInt32BE=function(e,t){return E(this,e,!1,t)},f.prototype.readFloatLE=function(e,t){return I(this,e,!0,t)},f.prototype.readFloatBE=function(e,t){return I(this,e,!1,t)},f.prototype.readDoubleLE=function(e,t){return A(this,e,!0,t)},f.prototype.readDoubleBE=function(e,t){return A(this,e,!1,t)},f.prototype.writeUInt8=function(e,t,n){n||(d(null!=e,\"missing value\"),d(null!=t,\"missing offset\"),d(t<this.length,\"trying to write beyond buffer length\"),Y(e,255)),t>=this.length||(this[t]=e)},f.prototype.writeUInt16LE=function(e,t,n){s(this,e,t,!0,n)},f.prototype.writeUInt16BE=function(e,t,n){s(this,e,t,!1,n)},f.prototype.writeUInt32LE=function(e,t,n){l(this,e,t,!0,n)},f.prototype.writeUInt32BE=function(e,t,n){l(this,e,t,!1,n)},f.prototype.writeInt8=function(e,t,n){n||(d(null!=e,\"missing value\"),d(null!=t,\"missing offset\"),d(t<this.length,\"Trying to write beyond buffer length\"),F(e,127,-128)),t>=this.length||(0<=e?this.writeUInt8(e,t,n):this.writeUInt8(255+e+1,t,n))},f.prototype.writeInt16LE=function(e,t,n){B(this,e,t,!0,n)},f.prototype.writeInt16BE=function(e,t,n){B(this,e,t,!1,n)},f.prototype.writeInt32LE=function(e,t,n){L(this,e,t,!0,n)},f.prototype.writeInt32BE=function(e,t,n){L(this,e,t,!1,n)},f.prototype.writeFloatLE=function(e,t,n){U(this,e,t,!0,n)},f.prototype.writeFloatBE=function(e,t,n){U(this,e,t,!1,n)},f.prototype.writeDoubleLE=function(e,t,n){x(this,e,t,!0,n)},f.prototype.writeDoubleBE=function(e,t,n){x(this,e,t,!1,n)},f.prototype.fill=function(e,t,n){if(t=t||0,n=n||this.length,d(\"number\"==typeof(e=\"string\"==typeof(e=e||0)?e.charCodeAt(0):e)&&!isNaN(e),\"value is not a number\"),d(t<=n,\"end < start\"),n!==t&&0!==this.length){d(0<=t&&t<this.length,\"start out of bounds\"),d(0<=n&&n<=this.length,\"end out of bounds\");for(var r=t;r<n;r++)this[r]=e}},f.prototype.inspect=function(){for(var e=[],t=this.length,n=0;n<t;n++)if(e[n]=k(this[n]),n===H.INSPECT_MAX_BYTES){e[n+1]=\"...\";break}return\"<Buffer \"+e.join(\" \")+\">\"},f.prototype.toArrayBuffer=function(){if(\"undefined\"==typeof Uint8Array)throw new Error(\"Buffer.toArrayBuffer not supported in this browser\");if(f._useTypedArrays)return new f(this).buffer;for(var e=new Uint8Array(this.length),t=0,n=e.length;t<n;t+=1)e[t]=this[t];return e.buffer};var t=f.prototype;function S(e,t,n){return\"number\"!=typeof e?n:t<=(e=~~e)?t:0<=e||0<=(e+=t)?e:0}function j(e){return(e=~~Math.ceil(+e))<0?0:e}function C(e){return(Array.isArray||function(e){return\"[object Array]\"===Object.prototype.toString.call(e)})(e)}function k(e){return e<16?\"0\"+e.toString(16):e.toString(16)}function T(e){for(var t=[],n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<=127)t.push(e.charCodeAt(n));else for(var o=n,i=(55296<=r&&r<=57343&&n++,encodeURIComponent(e.slice(o,n+1)).substr(1).split(\"%\")),u=0;u<i.length;u++)t.push(parseInt(i[u],16))}return t}function M(e){return a.toByteArray(e)}function c(e,t,n,r){for(var o=0;o<r&&!(o+n>=t.length||o>=e.length);o++)t[o+n]=e[o];return o}function N(e){try{return decodeURIComponent(e)}catch(e){return String.fromCharCode(65533)}}function Y(e,t){d(\"number\"==typeof e,\"cannot write a non-number as a number\"),d(0<=e,\"specified a negative value for writing an unsigned value\"),d(e<=t,\"value is larger than maximum value for type\"),d(Math.floor(e)===e,\"value has a fractional component\")}function F(e,t,n){d(\"number\"==typeof e,\"cannot write a non-number as a number\"),d(e<=t,\"value larger than maximum allowed value\"),d(n<=e,\"value smaller than minimum allowed value\"),d(Math.floor(e)===e,\"value has a fractional component\")}function D(e,t,n){d(\"number\"==typeof e,\"cannot write a non-number as a number\"),d(e<=t,\"value larger than maximum allowed value\"),d(n<=e,\"value smaller than minimum allowed value\")}function d(e,t){if(!e)throw new Error(t||\"Failed assertion\")}f._augment=function(e){return e._isBuffer=!0,e._get=e.get,e._set=e.set,e.get=t.get,e.set=t.set,e.write=t.write,e.toString=t.toString,e.toLocaleString=t.toString,e.toJSON=t.toJSON,e.copy=t.copy,e.slice=t.slice,e.readUInt8=t.readUInt8,e.readUInt16LE=t.readUInt16LE,e.readUInt16BE=t.readUInt16BE,e.readUInt32LE=t.readUInt32LE,e.readUInt32BE=t.readUInt32BE,e.readInt8=t.readInt8,e.readInt16LE=t.readInt16LE,e.readInt16BE=t.readInt16BE,e.readInt32LE=t.readInt32LE,e.readInt32BE=t.readInt32BE,e.readFloatLE=t.readFloatLE,e.readFloatBE=t.readFloatBE,e.readDoubleLE=t.readDoubleLE,e.readDoubleBE=t.readDoubleBE,e.writeUInt8=t.writeUInt8,e.writeUInt16LE=t.writeUInt16LE,e.writeUInt16BE=t.writeUInt16BE,e.writeUInt32LE=t.writeUInt32LE,e.writeUInt32BE=t.writeUInt32BE,e.writeInt8=t.writeInt8,e.writeInt16LE=t.writeInt16LE,e.writeInt16BE=t.writeInt16BE,e.writeInt32LE=t.writeInt32LE,e.writeInt32BE=t.writeInt32BE,e.writeFloatLE=t.writeFloatLE,e.writeFloatBE=t.writeFloatBE,e.writeDoubleLE=t.writeDoubleLE,e.writeDoubleBE=t.writeDoubleBE,e.fill=t.fill,e.inspect=t.inspect,e.toArrayBuffer=t.toArrayBuffer,e}}.call(this,O(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},O(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/buffer/index.js\",\"/node_modules/gulp-browserify/node_modules/buffer\")},{\"base64-js\":2,buffer:3,ieee754:10,lYpoI2:11}],4:[function(c,d,e){!function(e,t,a,n,r,o,i,u,s){var a=c(\"buffer\").Buffer,f=4,l=new a(f);l.fill(0);d.exports={hash:function(e,t,n,r){for(var o=t(function(e,t){e.length%f!=0&&(n=e.length+(f-e.length%f),e=a.concat([e,l],n));for(var n,r=[],o=t?e.readInt32BE:e.readInt32LE,i=0;i<e.length;i+=f)r.push(o.call(e,i));return r}(e=a.isBuffer(e)?e:new a(e),r),8*e.length),t=r,i=new a(n),u=t?i.writeInt32BE:i.writeInt32LE,s=0;s<o.length;s++)u.call(i,o[s],4*s,!0);return i}}}.call(this,c(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},c(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/helpers.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{buffer:3,lYpoI2:11}],5:[function(v,e,_){!function(l,c,u,d,h,p,g,y,w){var u=v(\"buffer\").Buffer,e=v(\"./sha\"),t=v(\"./sha256\"),n=v(\"./rng\"),b={sha1:e,sha256:t,md5:v(\"./md5\")},s=64,a=new u(s);function r(e,n){var r=b[e=e||\"sha1\"],o=[];return r||i(\"algorithm:\",e,\"is not yet supported\"),{update:function(e){return u.isBuffer(e)||(e=new u(e)),o.push(e),e.length,this},digest:function(e){var t=u.concat(o),t=n?function(e,t,n){u.isBuffer(t)||(t=new u(t)),u.isBuffer(n)||(n=new u(n)),t.length>s?t=e(t):t.length<s&&(t=u.concat([t,a],s));for(var r=new u(s),o=new u(s),i=0;i<s;i++)r[i]=54^t[i],o[i]=92^t[i];return n=e(u.concat([r,n])),e(u.concat([o,n]))}(r,n,t):r(t);return o=null,e?t.toString(e):t}}}function i(){var e=[].slice.call(arguments).join(\" \");throw new Error([e,\"we accept pull requests\",\"http://github.com/dominictarr/crypto-browserify\"].join(\"\\n\"))}a.fill(0),_.createHash=function(e){return r(e)},_.createHmac=r,_.randomBytes=function(e,t){if(!t||!t.call)return new u(n(e));try{t.call(this,void 0,new u(n(e)))}catch(e){t(e)}};var o,f=[\"createCredentials\",\"createCipher\",\"createCipheriv\",\"createDecipher\",\"createDecipheriv\",\"createSign\",\"createVerify\",\"createDiffieHellman\",\"pbkdf2\"],m=function(e){_[e]=function(){i(\"sorry,\",e,\"is not implemented yet\")}};for(o in f)m(f[o],o)}.call(this,v(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},v(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/index.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{\"./md5\":6,\"./rng\":7,\"./sha\":8,\"./sha256\":9,buffer:3,lYpoI2:11}],6:[function(w,b,e){!function(e,r,o,i,u,a,f,l,y){var t=w(\"./helpers\");function n(e,t){e[t>>5]|=128<<t%32,e[14+(t+64>>>9<<4)]=t;for(var n=1732584193,r=-271733879,o=-1732584194,i=271733878,u=0;u<e.length;u+=16){var s=n,a=r,f=o,l=i,n=c(n,r,o,i,e[u+0],7,-680876936),i=c(i,n,r,o,e[u+1],12,-389564586),o=c(o,i,n,r,e[u+2],17,606105819),r=c(r,o,i,n,e[u+3],22,-1044525330);n=c(n,r,o,i,e[u+4],7,-176418897),i=c(i,n,r,o,e[u+5],12,1200080426),o=c(o,i,n,r,e[u+6],17,-1473231341),r=c(r,o,i,n,e[u+7],22,-45705983),n=c(n,r,o,i,e[u+8],7,1770035416),i=c(i,n,r,o,e[u+9],12,-1958414417),o=c(o,i,n,r,e[u+10],17,-42063),r=c(r,o,i,n,e[u+11],22,-1990404162),n=c(n,r,o,i,e[u+12],7,1804603682),i=c(i,n,r,o,e[u+13],12,-40341101),o=c(o,i,n,r,e[u+14],17,-1502002290),n=d(n,r=c(r,o,i,n,e[u+15],22,1236535329),o,i,e[u+1],5,-165796510),i=d(i,n,r,o,e[u+6],9,-1069501632),o=d(o,i,n,r,e[u+11],14,643717713),r=d(r,o,i,n,e[u+0],20,-373897302),n=d(n,r,o,i,e[u+5],5,-701558691),i=d(i,n,r,o,e[u+10],9,38016083),o=d(o,i,n,r,e[u+15],14,-660478335),r=d(r,o,i,n,e[u+4],20,-405537848),n=d(n,r,o,i,e[u+9],5,568446438),i=d(i,n,r,o,e[u+14],9,-1019803690),o=d(o,i,n,r,e[u+3],14,-187363961),r=d(r,o,i,n,e[u+8],20,1163531501),n=d(n,r,o,i,e[u+13],5,-1444681467),i=d(i,n,r,o,e[u+2],9,-51403784),o=d(o,i,n,r,e[u+7],14,1735328473),n=h(n,r=d(r,o,i,n,e[u+12],20,-1926607734),o,i,e[u+5],4,-378558),i=h(i,n,r,o,e[u+8],11,-2022574463),o=h(o,i,n,r,e[u+11],16,1839030562),r=h(r,o,i,n,e[u+14],23,-35309556),n=h(n,r,o,i,e[u+1],4,-1530992060),i=h(i,n,r,o,e[u+4],11,1272893353),o=h(o,i,n,r,e[u+7],16,-155497632),r=h(r,o,i,n,e[u+10],23,-1094730640),n=h(n,r,o,i,e[u+13],4,681279174),i=h(i,n,r,o,e[u+0],11,-358537222),o=h(o,i,n,r,e[u+3],16,-722521979),r=h(r,o,i,n,e[u+6],23,76029189),n=h(n,r,o,i,e[u+9],4,-640364487),i=h(i,n,r,o,e[u+12],11,-421815835),o=h(o,i,n,r,e[u+15],16,530742520),n=p(n,r=h(r,o,i,n,e[u+2],23,-995338651),o,i,e[u+0],6,-198630844),i=p(i,n,r,o,e[u+7],10,1126891415),o=p(o,i,n,r,e[u+14],15,-1416354905),r=p(r,o,i,n,e[u+5],21,-57434055),n=p(n,r,o,i,e[u+12],6,1700485571),i=p(i,n,r,o,e[u+3],10,-1894986606),o=p(o,i,n,r,e[u+10],15,-1051523),r=p(r,o,i,n,e[u+1],21,-2054922799),n=p(n,r,o,i,e[u+8],6,1873313359),i=p(i,n,r,o,e[u+15],10,-30611744),o=p(o,i,n,r,e[u+6],15,-1560198380),r=p(r,o,i,n,e[u+13],21,1309151649),n=p(n,r,o,i,e[u+4],6,-145523070),i=p(i,n,r,o,e[u+11],10,-1120210379),o=p(o,i,n,r,e[u+2],15,718787259),r=p(r,o,i,n,e[u+9],21,-343485551),n=g(n,s),r=g(r,a),o=g(o,f),i=g(i,l)}return Array(n,r,o,i)}function s(e,t,n,r,o,i){return g((t=g(g(t,e),g(r,i)))<<o|t>>>32-o,n)}function c(e,t,n,r,o,i,u){return s(t&n|~t&r,e,t,o,i,u)}function d(e,t,n,r,o,i,u){return s(t&r|n&~r,e,t,o,i,u)}function h(e,t,n,r,o,i,u){return s(t^n^r,e,t,o,i,u)}function p(e,t,n,r,o,i,u){return s(n^(t|~r),e,t,o,i,u)}function g(e,t){var n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n}b.exports=function(e){return t.hash(e,n,16)}}.call(this,w(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},w(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/md5.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{\"./helpers\":4,buffer:3,lYpoI2:11}],7:[function(e,l,t){!function(e,t,n,r,o,i,u,s,f){var a;l.exports=a||function(e){for(var t,n=new Array(e),r=0;r<e;r++)0==(3&r)&&(t=4294967296*Math.random()),n[r]=t>>>((3&r)<<3)&255;return n}}.call(this,e(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},e(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/rng.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{buffer:3,lYpoI2:11}],8:[function(c,d,e){!function(e,t,n,r,o,s,a,f,l){var i=c(\"./helpers\");function u(l,c){l[c>>5]|=128<<24-c%32,l[15+(c+64>>9<<4)]=c;for(var e,t,n,r=Array(80),o=1732584193,i=-271733879,u=-1732584194,s=271733878,d=-1009589776,h=0;h<l.length;h+=16){for(var p=o,g=i,y=u,w=s,b=d,a=0;a<80;a++){r[a]=a<16?l[h+a]:v(r[a-3]^r[a-8]^r[a-14]^r[a-16],1);var f=m(m(v(o,5),(f=i,t=u,n=s,(e=a)<20?f&t|~f&n:!(e<40)&&e<60?f&t|f&n|t&n:f^t^n)),m(m(d,r[a]),(e=a)<20?1518500249:e<40?1859775393:e<60?-1894007588:-899497514)),d=s,s=u,u=v(i,30),i=o,o=f}o=m(o,p),i=m(i,g),u=m(u,y),s=m(s,w),d=m(d,b)}return Array(o,i,u,s,d)}function m(e,t){var n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n}function v(e,t){return e<<t|e>>>32-t}d.exports=function(e){return i.hash(e,u,20,!0)}}.call(this,c(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},c(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/sha.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{\"./helpers\":4,buffer:3,lYpoI2:11}],9:[function(c,d,e){!function(e,t,n,r,u,s,a,f,l){function b(e,t){var n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n}function o(e,l){var c,d=new Array(1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298),t=new Array(1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225),n=new Array(64);e[l>>5]|=128<<24-l%32,e[15+(l+64>>9<<4)]=l;for(var r,o,h=0;h<e.length;h+=16){for(var i=t[0],u=t[1],s=t[2],p=t[3],a=t[4],g=t[5],y=t[6],w=t[7],f=0;f<64;f++)n[f]=f<16?e[f+h]:b(b(b((o=n[f-2],m(o,17)^m(o,19)^v(o,10)),n[f-7]),(o=n[f-15],m(o,7)^m(o,18)^v(o,3))),n[f-16]),c=b(b(b(b(w,m(o=a,6)^m(o,11)^m(o,25)),a&g^~a&y),d[f]),n[f]),r=b(m(r=i,2)^m(r,13)^m(r,22),i&u^i&s^u&s),w=y,y=g,g=a,a=b(p,c),p=s,s=u,u=i,i=b(c,r);t[0]=b(i,t[0]),t[1]=b(u,t[1]),t[2]=b(s,t[2]),t[3]=b(p,t[3]),t[4]=b(a,t[4]),t[5]=b(g,t[5]),t[6]=b(y,t[6]),t[7]=b(w,t[7])}return t}var i=c(\"./helpers\"),m=function(e,t){return e>>>t|e<<32-t},v=function(e,t){return e>>>t};d.exports=function(e){return i.hash(e,o,32,!0)}}.call(this,c(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},c(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/sha256.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{\"./helpers\":4,buffer:3,lYpoI2:11}],10:[function(e,t,f){!function(e,t,n,r,o,i,u,s,a){f.read=function(e,t,n,r,o){var i,u,l=8*o-r-1,c=(1<<l)-1,d=c>>1,s=-7,a=n?o-1:0,f=n?-1:1,o=e[t+a];for(a+=f,i=o&(1<<-s)-1,o>>=-s,s+=l;0<s;i=256*i+e[t+a],a+=f,s-=8);for(u=i&(1<<-s)-1,i>>=-s,s+=r;0<s;u=256*u+e[t+a],a+=f,s-=8);if(0===i)i=1-d;else{if(i===c)return u?NaN:1/0*(o?-1:1);u+=Math.pow(2,r),i-=d}return(o?-1:1)*u*Math.pow(2,i-r)},f.write=function(e,t,l,n,r,c){var o,i,u=8*c-r-1,s=(1<<u)-1,a=s>>1,d=23===r?Math.pow(2,-24)-Math.pow(2,-77):0,f=n?0:c-1,h=n?1:-1,c=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(i=isNaN(t)?1:0,o=s):(o=Math.floor(Math.log(t)/Math.LN2),t*(n=Math.pow(2,-o))<1&&(o--,n*=2),2<=(t+=1<=o+a?d/n:d*Math.pow(2,1-a))*n&&(o++,n/=2),s<=o+a?(i=0,o=s):1<=o+a?(i=(t*n-1)*Math.pow(2,r),o+=a):(i=t*Math.pow(2,a-1)*Math.pow(2,r),o=0));8<=r;e[l+f]=255&i,f+=h,i/=256,r-=8);for(o=o<<r|i,u+=r;0<u;e[l+f]=255&o,f+=h,o/=256,u-=8);e[l+f-h]|=128*c}}.call(this,e(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},e(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/ieee754/index.js\",\"/node_modules/gulp-browserify/node_modules/ieee754\")},{buffer:3,lYpoI2:11}],11:[function(e,h,t){!function(e,t,n,r,o,f,l,c,d){var i,u,s;function a(){}(e=h.exports={}).nextTick=(u=\"undefined\"!=typeof window&&window.setImmediate,s=\"undefined\"!=typeof window&&window.postMessage&&window.addEventListener,u?function(e){return window.setImmediate(e)}:s?(i=[],window.addEventListener(\"message\",function(e){var t=e.source;t!==window&&null!==t||\"process-tick\"!==e.data||(e.stopPropagation(),0<i.length&&i.shift()())},!0),function(e){i.push(e),window.postMessage(\"process-tick\",\"*\")}):function(e){setTimeout(e,0)}),e.title=\"browser\",e.browser=!0,e.env={},e.argv=[],e.on=a,e.addListener=a,e.once=a,e.off=a,e.removeListener=a,e.removeAllListeners=a,e.emit=a,e.binding=function(e){throw new Error(\"process.binding is not supported\")},e.cwd=function(){return\"/\"},e.chdir=function(e){throw new Error(\"process.chdir is not supported\")}}.call(this,e(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},e(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/process/browser.js\",\"/node_modules/gulp-browserify/node_modules/process\")},{buffer:3,lYpoI2:11}]},{},[1])(1)});", "module.exports = function pad (num, size) {\n var s = '000000000' + num;\n return s.substr(s.length - size);\n};\n", "var pad = require('./pad.js');\n\nvar env = typeof window === 'object' ? window : self;\nvar globalCount = Object.keys(env).length;\nvar mimeTypesLength = navigator.mimeTypes ? navigator.mimeTypes.length : 0;\nvar clientId = pad((mimeTypesLength +\n navigator.userAgent.length).toString(36) +\n globalCount.toString(36), 4);\n\nmodule.exports = function fingerprint () {\n return clientId;\n};\n", "\nvar getRandomValue;\n\nvar crypto = typeof window !== 'undefined' &&\n (window.crypto || window.msCrypto) ||\n typeof self !== 'undefined' &&\n self.crypto;\n\nif (crypto) {\n var lim = Math.pow(2, 32) - 1;\n getRandomValue = function () {\n return Math.abs(crypto.getRandomValues(new Uint32Array(1))[0] / lim);\n };\n} else {\n getRandomValue = Math.random;\n}\n\nmodule.exports = getRandomValue;\n", "/**\n * cuid.js\n * Collision-resistant UID generator for browsers and node.\n * Sequential for fast db lookups and recency sorting.\n * Safe for element IDs and server-side lookups.\n *\n * Extracted from CLCTR\n *\n * Copyright (c) Eric Elliott 2012\n * MIT License\n */\n\nvar fingerprint = require('./lib/fingerprint.js');\nvar pad = require('./lib/pad.js');\nvar getRandomValue = require('./lib/getRandomValue.js');\n\nvar c = 0,\n blockSize = 4,\n base = 36,\n discreteValues = Math.pow(base, blockSize);\n\nfunction randomBlock () {\n return pad((getRandomValue() *\n discreteValues << 0)\n .toString(base), blockSize);\n}\n\nfunction safeCounter () {\n c = c < discreteValues ? c : 0;\n c++; // this is not subliminal\n return c - 1;\n}\n\nfunction cuid () {\n // Starting with a lowercase letter makes\n // it HTML element ID friendly.\n var letter = 'c', // hard-coded allows for sequential access\n\n // timestamp\n // warning: this exposes the exact date and time\n // that the uid was created.\n timestamp = (new Date().getTime()).toString(base),\n\n // Prevent same-machine collisions.\n counter = pad(safeCounter().toString(base), blockSize),\n\n // A few chars to generate distinct ids for different\n // clients (so different computers are far less\n // likely to generate the same id)\n print = fingerprint(),\n\n // Grab some more chars from Math.random()\n random = randomBlock() + randomBlock();\n\n return letter + timestamp + counter + print + random;\n}\n\ncuid.slug = function slug () {\n var date = new Date().getTime().toString(36),\n counter = safeCounter().toString(36).slice(-4),\n print = fingerprint().slice(0, 1) +\n fingerprint().slice(-1),\n random = randomBlock().slice(-2);\n\n return date.slice(-2) +\n counter + print + random;\n};\n\ncuid.isCuid = function isCuid (stringToCheck) {\n if (typeof stringToCheck !== 'string') return false;\n if (stringToCheck.startsWith('c')) return true;\n return false;\n};\n\ncuid.isSlug = function isSlug (stringToCheck) {\n if (typeof stringToCheck !== 'string') return false;\n var stringLength = stringToCheck.length;\n if (stringLength >= 7 && stringLength <= 10) return true;\n return false;\n};\n\ncuid.fingerprint = fingerprint;\n\nmodule.exports = cuid;\n", "/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n function next() {\n while (env.stack.length) {\n var rec = env.stack.pop();\n try {\n var result = rec.dispose && rec.dispose.call(rec.value);\n if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n catch (e) {\n fail(e);\n }\n }\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n};\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=typed-event-interfaces.js.map", null, null, null, null, null, null, null, null, "import { Client } from './client/Client.js';\nimport type { ContextInit } from './context/context.js';\nexport type { ClientWithCollections } from './client/Client.js';\nexport { Client, type ClientDescriptorOptions, type ClientInitOptions };\ntype ClientInitOptions = ContextInit;\n/** @deprecated - use ClientInitOptions alias */\ntype ClientDescriptorOptions = ClientInitOptions;\n// backward compat\nexport { createMigration, schema } from '@verdant-web/common';\nexport type {\n\tCollectionFilter,\n\tDocumentBaseline,\n\tFileData,\n\tIndexValueTag,\n\tMigration,\n\tObjectIdentifier,\n\tStorageAnyFieldSchema,\n\tStorageArrayFieldSchema,\n\tStorageBooleanFieldSchema,\n\tStorageCollectionSchema,\n\tStorageDocument,\n\tStorageFieldSchema,\n\tStorageFieldsSchema,\n\tStorageFileFieldSchema,\n\tStorageMapFieldSchema,\n\tStorageNumberFieldSchema,\n\tStorageObjectFieldSchema,\n\tStorageSchema,\n\tStorageStringFieldSchema,\n\tUserInfo,\n\tVerdantError,\n\tVerdantErrorCode,\n} from '@verdant-web/common';\nexport * from './authorization.js';\nexport { Entity, getEntityClient } from './entities/Entity.js';\nexport type {\n\tAccessibleEntityProperty,\n\tAnyEntity,\n\tEntityDestructured,\n\tEntityInit,\n\tEntityShape,\n\tListEntity,\n\tObjectEntity,\n} from './entities/types.js';\nexport { EntityFile, type EntityFileSnapshot } from './files/EntityFile.js';\nexport * from './logger.js';\nexport { IdbPersistence } from './persistence/idb/idbPersistence.js';\nexport type * from './persistence/interfaces.js';\nexport type { QueryStatus } from './queries/BaseQuery.js';\nexport type { CollectionQueries } from './queries/CollectionQueries.js';\nexport type { Query } from './queries/types.js';\nexport * from './sync/cliSync.js';\nexport { ServerSync, type ServerSyncOptions } from './sync/Sync.js';\nexport type { SyncTransportMode } from './sync/Sync.js';\nexport { UndoHistory } from './UndoHistory.js';\nexport * from './utils/id.js';\nexport { Client as Storage };\n", "import { DocumentBaseline } from './baseline.js';\nimport { Operation } from './operation.js';\n\nfunction encode(str: string): AuthorizationKey {\n\tif (typeof Buffer !== 'undefined') {\n\t\tconst val = Buffer.from(str).toString('base64');\n\t\treturn val as AuthorizationKey;\n\t}\n\tconst val = btoa(str);\n\treturn val as AuthorizationKey;\n}\n\nfunction decode(str: string): string {\n\tif (typeof Buffer !== 'undefined') {\n\t\treturn Buffer.from(str, 'base64').toString();\n\t}\n\treturn atob(str);\n}\n\nexport type AuthorizationKey = string & {\n\t// virtual type only used for type checking to try to sort\n\t// out between encoded and decoded string values.\n\t'@@type': 'authz';\n};\n\nexport const authz = {\n\tonlyUser: (userId: string): AuthorizationKey => encode(`u:${userId}:*`),\n\tonlyMe: (): AuthorizationKey => authz.onlyUser(ORIGINATOR_SUBJECT),\n\tdecode: (encoded: string) => {\n\t\tconst decoded = decode(encoded);\n\t\tconst parts = decoded.split(':');\n\t\tif (parts.length !== 3) {\n\t\t\tthrow new Error('Invalid authz string');\n\t\t}\n\t\treturn {\n\t\t\tscope: parts[0],\n\t\t\tsubject: parts[1],\n\t\t\taction: parts[2],\n\t\t};\n\t},\n};\n\nexport const ORIGINATOR_SUBJECT = '$$_originator_$$';\n\n/**\n * Rewrites the special \"originator\" constant subject (used by\n * local-only clients) to the given user ID.\n *\n * Used to initialize a library from a local-only replica\n */\nexport function rewriteAuthzOriginator(\n\tdata: { operations?: Operation[]; baselines?: DocumentBaseline[] },\n\tnewSubject: string,\n) {\n\tconst { operations, baselines } = data;\n\tif (operations) {\n\t\tfor (const op of operations) {\n\t\t\tif (op.authz) {\n\t\t\t\tconst decoded = authz.decode(op.authz);\n\t\t\t\tif (decoded.subject === ORIGINATOR_SUBJECT) {\n\t\t\t\t\top.authz = authz.onlyUser(newSubject);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif (baselines) {\n\t\tfor (const baseline of baselines) {\n\t\t\tif (baseline.authz) {\n\t\t\t\tconst decoded = authz.decode(baseline.authz);\n\t\t\t\tif (decoded.subject === ORIGINATOR_SUBJECT) {\n\t\t\t\t\tbaseline.authz = authz.onlyUser(newSubject);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n", "export class Batcher<T, UserData = any> {\n\tprivate batches: Map<string, Batch<T, UserData>> = new Map();\n\n\tconstructor(\n\t\tprivate flusher: (items: T[], batchKey: string, userData: UserData) => any,\n\t) {}\n\n\tadd({\n\t\tkey,\n\t\tuserData,\n\t\titems,\n\t\tmax,\n\t\ttimeout,\n\t}: {\n\t\tkey: string;\n\t\tuserData?: UserData;\n\t\titems: T[];\n\t\tmax?: number | null;\n\t\ttimeout?: number | null;\n\t}) {\n\t\tlet batch = this.batches.get(key);\n\t\tif (!batch) {\n\t\t\tbatch = new Batch({\n\t\t\t\tmax: max || null,\n\t\t\t\tstartedAt: Date.now(),\n\t\t\t\tuserData,\n\t\t\t\ttimeout: timeout || null,\n\t\t\t\tflusher: this.flusher,\n\t\t\t\tkey,\n\t\t\t});\n\t\t\tthis.batches.set(key, batch);\n\t\t}\n\t\tbatch.update({\n\t\t\titems,\n\t\t\tmax,\n\t\t\ttimeout,\n\t\t\tuserData,\n\t\t});\n\n\t\treturn batch;\n\t}\n\n\tflush = (key: string) => {\n\t\tconst batch = this.batches.get(key);\n\t\tif (!batch) return;\n\n\t\treturn batch.flush();\n\t};\n\n\tdiscard = (key: string) => {\n\t\tconst batch = this.batches.get(key);\n\t\tif (!batch) return;\n\n\t\tbatch.discard();\n\t\tthis.batches.delete(key);\n\t};\n\n\tflushAll = () => {\n\t\treturn [...this.batches.values()].map((batch) => batch.flush());\n\t};\n\n\tgetSize = (key: string) => {\n\t\tconst batch = this.batches.get(key);\n\t\tif (!batch) return 0;\n\n\t\treturn batch.items.length;\n\t};\n}\n\nexport class Batch<T, UserData = any> {\n\titems: Array<T> = [];\n\tmax: number | null;\n\tstartedAt: number;\n\ttimeout: number | null;\n\tflushTimeout?: NodeJS.Timeout;\n\tuserData?: any;\n\tflusher: (items: T[], batchKey: string, userData: UserData) => any;\n\tkey: string;\n\n\tconstructor({\n\t\tmax,\n\t\tstartedAt,\n\t\ttimeout,\n\t\tuserData,\n\t\tflusher,\n\t\tkey,\n\t}: {\n\t\tkey: string;\n\t\tmax: number | null;\n\t\tstartedAt: number;\n\t\ttimeout: number | null;\n\t\tuserData?: UserData;\n\t\tflusher: (items: T[], batchKey: string, userData: UserData) => any;\n\t}) {\n\t\tthis.max = max;\n\t\tthis.startedAt = startedAt;\n\t\tthis.timeout = timeout;\n\t\tthis.userData = userData;\n\t\tthis.flusher = flusher;\n\t\tthis.key = key;\n\t}\n\n\tupdate = ({\n\t\titems,\n\t\tmax,\n\t\ttimeout,\n\t\tuserData,\n\t}: {\n\t\titems: Array<T>;\n\t\tmax?: number | null;\n\t\ttimeout?: number | null;\n\t\tuserData?: UserData;\n\t}) => {\n\t\tthis.items.push(...items);\n\t\tif (max !== undefined) this.max = max;\n\t\tif (timeout !== undefined) this.timeout = timeout;\n\t\tif (userData) this.userData = userData;\n\n\t\t// if the batch has items and a timeout but has not\n\t\t// scheduled yet, schedule it\n\t\tconst needsSchedule =\n\t\t\tthis.items.length !== 0 && this.timeout !== null && !this.flushTimeout;\n\n\t\t// if the batch has already reached its max, skip scheduling\n\t\t// and flush immediately\n\t\tif (this.max !== null && this.items.length >= this.max) {\n\t\t\tthis.flush();\n\t\t} else if (needsSchedule && this.timeout !== null) {\n\t\t\tthis.flushTimeout = setTimeout(this.flush, this.timeout);\n\t\t}\n\t};\n\n\tflush = () => {\n\t\tthis.flushTimeout && clearTimeout(this.flushTimeout);\n\t\tthis.flushTimeout = undefined;\n\t\tconst items = this.items;\n\t\tthis.items = [];\n\t\treturn this.flusher(items, this.key, this.userData);\n\t};\n\n\tdiscard = () => {\n\t\tthis.flushTimeout && clearTimeout(this.flushTimeout);\n\t\tthis.flushTimeout = undefined;\n\t\tthis.items = [];\n\t};\n}\n", "export enum VerdantErrorCode {\n\tInvalidRequest = 4000,\n\tBodyRequired = 4001,\n\tNoToken = 4010,\n\tInvalidToken = 4011,\n\tTokenExpired = 4012,\n\tForbidden = 4030,\n\tNotFound = 4040,\n\tUnexpected = 5000,\n\tConfigurationError = 5010,\n\tNoFileStorage = 5011,\n\n\t// Client errors\n\n\tMigrationPathNotFound = 7001,\n\tImportFailed = 7002,\n\t// some functionality was invoked which requires online status, and\n\t// client couldn't connect.\n\tOffline = 7003,\n}\n\nexport class VerdantError extends Error {\n\tstatic Code = VerdantErrorCode;\n\n\tconstructor(\n\t\tpublic code: VerdantErrorCode,\n\t\tcause?: Error | undefined,\n\t\tmessage?: string,\n\t) {\n\t\tsuper(message ?? `Verdant error: ${code}`, {\n\t\t\tcause,\n\t\t});\n\t}\n\n\tget httpStatus() {\n\t\tconst status = Math.floor(this.code / 10);\n\t\tif (status < 600) {\n\t\t\treturn status;\n\t\t}\n\t\treturn 500;\n\t}\n\n\ttoResponse = () => {\n\t\treturn JSON.stringify({\n\t\t\tcode: this.code,\n\t\t});\n\t};\n}\n\nexport function isVerdantErrorResponse(body: any): body is { code: number } {\n\treturn (\n\t\ttypeof body === 'object' && 'code' in body && typeof body.code === 'number'\n\t);\n}\n", "// Unique ID creation requires a high quality random # generator. In the browser we therefore\n// require the crypto API and do not support built-in fallback to lower quality random number\n// generators (like Math.random()).\nvar getRandomValues;\nvar rnds8 = new Uint8Array(16);\nexport default function rng() {\n // lazy load so that environments that need to polyfill have a chance to do so\n if (!getRandomValues) {\n // getRandomValues needs to be invoked in a context where \"this\" is a Crypto implementation. Also,\n // find the complete implementation of crypto (msCrypto) on IE11.\n getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);\n\n if (!getRandomValues) {\n throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');\n }\n }\n\n return getRandomValues(rnds8);\n}", "export default /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;", "import REGEX from './regex.js';\n\nfunction validate(uuid) {\n return typeof uuid === 'string' && REGEX.test(uuid);\n}\n\nexport default validate;", "import validate from './validate.js';\n/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\n\nvar byteToHex = [];\n\nfor (var i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).substr(1));\n}\n\nfunction stringify(arr) {\n var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n // Note: Be careful editing this code! It's been tuned for performance\n // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434\n var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one\n // of the following:\n // - One or more input array values don't map to a hex octet (leading to\n // \"undefined\" in the uuid)\n // - Invalid input values for the RFC `version` or `variant` fields\n\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n\n return uuid;\n}\n\nexport default stringify;", "import rng from './rng.js';\nimport stringify from './stringify.js';\n\nfunction v4(options, buf, offset) {\n options = options || {};\n var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n\n rnds[6] = rnds[6] & 0x0f | 0x40;\n rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided\n\n if (buf) {\n offset = offset || 0;\n\n for (var i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n\n return buf;\n }\n\n return stringify(rnds);\n}\n\nexport default v4;", "import hash from 'object-hash';\nimport { v4 } from 'uuid';\nimport { assignOid, maybeGetOid } from './oids.js';\n\nexport function take<T extends object, Keys extends keyof T>(\n\tobj: T,\n\tkeys: Keys[],\n): Pick<T, Keys> {\n\tconst result: any = {};\n\tfor (const key of keys) {\n\t\tresult[key] = obj[key];\n\t}\n\treturn result;\n}\n\nexport function omit<T extends object, Keys extends keyof T>(\n\tobj: T,\n\tkeys: Keys[],\n): Omit<T, Keys> {\n\tconst result: any = {};\n\tfor (const key of Object.keys(obj)) {\n\t\tif (!keys.includes(key as Keys)) {\n\t\t\tresult[key] = (obj as any)[key];\n\t\t}\n\t}\n\treturn result;\n}\n\nexport function getSortedIndex<T>(\n\tarray: T[],\n\tinsert: T,\n\tcompare: (a: T, b: T) => number,\n) {\n\tlet low = 0;\n\tlet high = array.length;\n\twhile (low < high) {\n\t\tconst mid = (low + high) >>> 1;\n\t\tconst cmp = compare(array[mid], insert);\n\t\tif (cmp < 0) {\n\t\t\tlow = mid + 1;\n\t\t} else {\n\t\t\thigh = mid;\n\t\t}\n\t}\n\treturn low;\n}\n\nfunction orderedReplacer(k: any, v: any) {\n\tif (typeof v !== 'object' || v === null || Array.isArray(v)) {\n\t\treturn v;\n\t}\n\treturn Object.fromEntries(\n\t\tObject.entries(v).sort(([ka], [kb]) => (ka < kb ? -1 : ka > kb ? 1 : 0)),\n\t);\n}\n/**\n * Consistently stringifies an object regardless\n * of key insertion order\n */\nexport function stableStringify(obj: any) {\n\tconst seen = new WeakMap();\n\tlet cyclicCount = 0;\n\treturn JSON.stringify(obj, (k, v) => {\n\t\tif (typeof v === 'object' && v !== null) {\n\t\t\tif (seen.has(v)) {\n\t\t\t\treturn { $ref: seen.get(v) };\n\t\t\t}\n\t\t\tseen.set(v, `cyclic-ref:${cyclicCount++}`);\n\t\t}\n\t\treturn orderedReplacer(k, v);\n\t});\n}\n\n/**\n * A version of structured cloning which preserves object identity\n * references in the system.\n */\nexport function cloneDeep<T>(obj: T, copyOids = true): T {\n\t// shortcut... if OIDs aren't important, we can use the built-in\n\t// structured cloning algorithm which should be faster.\n\tif (!copyOids && typeof structuredClone === 'function') {\n\t\treturn structuredClone(obj);\n\t}\n\n\tif (isObject(obj) || Array.isArray(obj)) {\n\t\tconst oid = maybeGetOid(obj);\n\t\tlet clone: any;\n\t\tif (Array.isArray(obj)) {\n\t\t\tclone = obj.map((v) => cloneDeep(v, copyOids)) as T;\n\t\t} else {\n\t\t\tclone = {};\n\t\t\tfor (const [key, value] of Object.entries(obj as any)) {\n\t\t\t\tclone[key] = cloneDeep(value, copyOids);\n\t\t\t}\n\t\t}\n\t\tif (copyOids && oid) {\n\t\t\tassignOid(clone, oid);\n\t\t}\n\t\treturn clone;\n\t}\n\treturn obj;\n}\n\n// TODO: better hash\nexport function hashObject(obj: any) {\n\t// hash the object into a unique string\n\treturn hash(obj);\n}\n\nexport function isObject(obj: any) {\n\treturn obj && typeof obj === 'object';\n}\n\nexport function roughSizeOfObject(object: any) {\n\tvar objectList = [];\n\tvar stack = [object];\n\tvar bytes = 0;\n\n\twhile (stack.length) {\n\t\tvar value = stack.pop();\n\n\t\tif (typeof value === 'boolean') {\n\t\t\tbytes += 4;\n\t\t} else if (typeof value === 'string') {\n\t\t\tbytes += value.length * 2;\n\t\t} else if (typeof value === 'number') {\n\t\t\tbytes += 8;\n\t\t} else if (typeof value === 'object' && objectList.indexOf(value) === -1) {\n\t\t\tobjectList.push(value);\n\n\t\t\tfor (var i in value) {\n\t\t\t\tstack.push(value[i]);\n\t\t\t}\n\t\t}\n\t}\n\treturn bytes;\n}\n\nexport function assert(\n\tcondition: any,\n\tmessage: string = 'assertion failed',\n): asserts condition {\n\tif (!condition) {\n\t\tthrow new Error(message);\n\t}\n}\n\nexport function generateId(length = 16) {\n\treturn v4().replace('-', '').slice(0, length);\n}\n\nexport function findLastIndex<T>(array: T[], predicate: (item: T) => boolean) {\n\tfor (let i = array.length - 1; i >= 0; i--) {\n\t\tif (predicate(array[i])) {\n\t\t\treturn i;\n\t\t}\n\t}\n\treturn -1;\n}\n\nexport function debounce<T extends (...args: any[]) => any>(\n\tfn: T,\n\twait: number,\n): T {\n\tlet timeout: any;\n\treturn function (this: any, ...args: any[]) {\n\t\tconst context = this;\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(() => fn.apply(context, args), wait);\n\t} as any;\n}\n\nexport function throttle<T extends (...args: any[]) => any>(\n\tfn: T,\n\twait: number,\n): T {\n\tlet lastTime = 0;\n\n\t// invoke once for the last call\n\tlet trailingTimeout: any;\n\n\treturn function (this: any, ...args: any[]) {\n\t\tconst context = this;\n\t\tconst now = Date.now();\n\t\tif (now - lastTime >= wait) {\n\t\t\tlastTime = now;\n\t\t\tfn.apply(context, args);\n\t\t\tclearTimeout(trailingTimeout);\n\t\t} else {\n\t\t\tclearTimeout(trailingTimeout);\n\t\t\ttrailingTimeout = setTimeout(() => {\n\t\t\t\tlastTime = now;\n\t\t\t\tfn.apply(context, args);\n\t\t\t}, wait);\n\t\t}\n\t} as any;\n}\n\nexport function noop() {}\n\n// avoids recursion and other issues with JSON.stringify\nexport function safeStringify(obj: any) {\n\ttry {\n\t\treturn JSON.stringify(obj);\n\t} catch (e) {\n\t\treturn `[recursive/invalid:${String(obj)}]`;\n\t}\n}\n", "import { isObject } from './utils.js';\n\nexport type FileRef = {\n\t'@@type': 'file';\n\tid: string;\n};\n\nexport function isFileRef(value: any): value is FileRef {\n\treturn value && value['@@type'] === 'file';\n}\nexport function createFileRef(id: string): FileRef {\n\treturn {\n\t\t'@@type': 'file',\n\t\tid,\n\t};\n}\n\nexport type FileData = {\n\tid: string;\n\t/**\n\t * For locally created files, this starts false, until it's uploaded\n\t * Remote files this is always true\n\t */\n\tremote: boolean;\n\tname: string;\n\ttype: string;\n\t/** A local File instance, if available. */\n\tfile?: Blob | null;\n\t/** The server URL of this file. */\n\turl?: string | null;\n\t/** Local filesystem path for the file. Only used in environments with direct fs access. */\n\tlocalPath?: string;\n\t/** The time this file was added, if available. */\n\ttimestamp?: string;\n};\n\nexport function getAllFileFields(snapshot: any): [string, FileRef][] {\n\treturn Object.entries(snapshot).filter((entry) => isFileRef(entry[1])) as [\n\t\tstring,\n\t\tFileRef,\n\t][];\n}\n\nexport function isFile(value: any) {\n\tif (typeof File !== 'undefined' && value instanceof File) {\n\t\treturn true;\n\t}\n\tif (typeof Blob !== 'undefined' && value instanceof Blob) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nexport function isFileData(value: any): value is FileData {\n\treturn (\n\t\tvalue &&\n\t\tisObject(value) &&\n\t\ttypeof value.id === 'string' &&\n\t\ttypeof value.remote === 'boolean' &&\n\t\ttypeof value.name === 'string' &&\n\t\ttypeof value.type === 'string'\n\t);\n}\n", "import { FileRef, isFileRef } from './files.js';\nimport { isObjectRef, ObjectRef } from './operation.js';\n\nexport function isRef(obj: any): obj is ObjectRef | FileRef {\n\treturn isObjectRef(obj) || isFileRef(obj);\n}\n\nexport function compareRefs(a: any, b: any) {\n\tif (a === b) return true;\n\tif (!isRef(a) || !isRef(b)) return false;\n\tif (a['@@type'] !== b['@@type']) return false;\n\tif (a.id !== b.id) return false;\n\treturn true;\n}\n\nexport type Ref = ObjectRef | FileRef;\n\nexport function makeObjectRef(oid: string): ObjectRef {\n\treturn { '@@type': 'ref', id: oid };\n}\n\nexport function makeFileRef(oid: string): FileRef {\n\treturn { '@@type': 'file', id: oid };\n}\n", "import { AuthorizationKey } from './authz.js';\nimport { DocumentBaseline } from './baseline.js';\nimport { FileRef, isFileRef } from './files.js';\nimport {\n\tassignOid,\n\tassignOidsToAllSubObjects,\n\tgetOid,\n\tgetOidRoot,\n\tmaybeGetOid,\n\tnormalize,\n\tObjectIdentifier,\n\tremoveOid,\n} from './oids.js';\nimport { compareRefs, isRef } from './refs.js';\nimport { assert, cloneDeep, findLastIndex, isObject } from './utils.js';\n\n// export type ObjectIdentifier<\n// \tCollectionName extends string = string,\n// \tDocumentId extends string = string,\n// \tDocumentOid extends string = string,\n// > =\n// \t| `${CollectionName}/${DocumentId}:${DocumentOid}`\n// \t| `${CollectionName}/${DocumentId}:${DocumentOid}#${string}`;\n\nexport type ObjectRef = {\n\t'@@type': 'ref';\n\tid: ObjectIdentifier;\n};\n\nexport function isObjectRef(obj: any): obj is ObjectRef {\n\treturn obj && typeof obj === 'object' && obj['@@type'] === 'ref';\n}\n\nexport type Normalized<T> = {\n\t[key in keyof T]: T[key] extends Object ? ObjectRef : T[key];\n};\n\n// patches v2\n\nexport type PropertyName = string | number;\n/**\n * List patches can target a particular child list or\n * nested lists. The first path item is the property path\n * of the first child list, any subsequent values are nested\n * list indices.\n */\nexport type PropertyValue =\n\t| string\n\t| number\n\t| boolean\n\t| null\n\t| undefined\n\t| ObjectRef\n\t| FileRef;\n\n// all patches refer to a specific sub-object.\ninterface BaseOperationPatch {}\n\nexport interface OperationPatchInitialize extends BaseOperationPatch {\n\top: 'initialize';\n\tvalue: any;\n}\nexport interface OperationPatchSet extends BaseOperationPatch {\n\top: 'set';\n\tname: PropertyName;\n\tvalue: PropertyValue;\n}\nexport interface OperationPatchRemove extends BaseOperationPatch {\n\top: 'remove';\n\tname: PropertyName;\n}\nexport interface OperationPatchListSet extends BaseOperationPatch {\n\top: 'list-set';\n\tindex: number;\n\tvalue: PropertyValue;\n}\nexport interface OperationPatchListPush extends BaseOperationPatch {\n\top: 'list-push';\n\tvalue: PropertyValue;\n}\nexport interface OperationPatchListInsert extends BaseOperationPatch {\n\top: 'list-insert';\n\tindex: number;\n\tvalue?: PropertyValue;\n\tvalues?: PropertyValue[];\n}\nexport interface OperationPatchListDelete extends BaseOperationPatch {\n\top: 'list-delete';\n\tindex: number;\n\tcount: number;\n}\n/**\n * Optimal for lists of object references. Moves\n * the selected item to the target index even if it\n * is not at the original index anymore.\n */\nexport interface OperationPatchListMoveByRef extends BaseOperationPatch {\n\top: 'list-move-by-ref';\n\tvalue: ObjectRef | FileRef;\n\tindex: number;\n}\n/**\n * Suitable for any list move, whether object lists\n * or primitive lists.\n */\nexport interface OperationPatchListMoveByIndex extends BaseOperationPatch {\n\top: 'list-move-by-index';\n\tfrom: number;\n\tto: number;\n}\n/**\n * Removes all instances of the value from\n * the list. Good for set behavior or removing\n * a specific item even if it changes index\n * from conflicts.\n */\nexport interface OperationPatchListRemove extends BaseOperationPatch {\n\top: 'list-remove';\n\tvalue: PropertyValue;\n\tonly?: 'first' | 'last';\n}\n\nexport interface OperationPatchListAdd extends BaseOperationPatch {\n\top: 'list-add';\n\tvalue: PropertyValue;\n}\n\nexport interface OperationPatchDelete extends BaseOperationPatch {\n\top: 'delete';\n}\n\nexport interface OperationPatchTouch extends BaseOperationPatch {\n\top: 'touch';\n}\n\nexport type OperationPatch =\n\t| OperationPatchInitialize\n\t| OperationPatchSet\n\t| OperationPatchRemove\n\t| OperationPatchListSet\n\t| OperationPatchListPush\n\t| OperationPatchListInsert\n\t| OperationPatchListDelete\n\t| OperationPatchListMoveByRef\n\t| OperationPatchListMoveByIndex\n\t| OperationPatchListRemove\n\t| OperationPatchDelete\n\t| OperationPatchListAdd\n\t| OperationPatchTouch;\n\nexport type Operation = {\n\toid: ObjectIdentifier;\n\ttimestamp: string;\n\tdata: OperationPatch;\n\tauthz?: AuthorizationKey;\n};\n\n/**\n * Takes a basic object and constructs a patch list to create it and\n * all of its nested objects.\n */\nexport function initialToPatches(\n\tinitial: any,\n\trootOid: ObjectIdentifier,\n\tgetNow: () => string,\n\tcreateSubId?: () => string,\n\tpatches: Operation[] = [],\n\toptions?: { authz?: AuthorizationKey },\n) {\n\tassignOid(initial, rootOid);\n\tassignOidsToAllSubObjects(initial, createSubId);\n\tconst normalized = normalize(initial);\n\tfor (const key of normalized.keys()) {\n\t\tconst value = normalized.get(key);\n\t\tconst op: Operation = {\n\t\t\toid: key,\n\t\t\ttimestamp: getNow(),\n\t\t\tdata: {\n\t\t\t\top: 'initialize',\n\t\t\t\tvalue: removeOid(value),\n\t\t\t},\n\t\t};\n\t\tpatches.push(addAuthzToOp(op, options?.authz));\n\t}\n\treturn patches;\n}\n\nexport function shallowInitialToPatches(\n\tinitial: any,\n\trootOid: ObjectIdentifier,\n\tgetNow: () => string,\n\tpatches: Operation[] = [],\n\toptions?: { authz?: AuthorizationKey },\n) {\n\tconst op: Operation = {\n\t\toid: rootOid,\n\t\ttimestamp: getNow(),\n\t\tdata: {\n\t\t\top: 'initialize',\n\t\t\tvalue: initial,\n\t\t},\n\t};\n\tpatches.push(addAuthzToOp(op, options?.authz));\n\treturn patches;\n}\n\n// saves a bit of network traffic by not attaching authz\n// key at all if not present\nexport function addAuthzToOp(op: Operation, authz?: AuthorizationKey) {\n\tif (authz) {\n\t\top.authz = authz;\n\t}\n\treturn op;\n}\n\nexport function groupPatchesByOid(patches: Operation[]) {\n\tconst grouped: Record<ObjectIdentifier, Operation[]> = {};\n\tfor (const patch of patches) {\n\t\tif (patch.oid in grouped) {\n\t\t\tgrouped[patch.oid].push(patch);\n\t\t} else {\n\t\t\tgrouped[patch.oid] = [patch];\n\t\t}\n\t}\n\treturn grouped;\n}\n\nexport function groupPatchesByRootOid(patches: Operation[]) {\n\tconst grouped: Record<ObjectIdentifier, Operation[]> = {};\n\tfor (const patch of patches) {\n\t\tconst root = getOidRoot(patch.oid);\n\t\tif (root in grouped) {\n\t\t\tgrouped[root].push(patch);\n\t\t} else {\n\t\t\tgrouped[root] = [patch];\n\t\t}\n\t}\n\treturn grouped;\n}\n\nexport function groupBaselinesByRootOid(baselines: DocumentBaseline[]) {\n\tconst grouped: Record<ObjectIdentifier, DocumentBaseline[]> = {};\n\tfor (const patch of baselines) {\n\t\tconst root = getOidRoot(patch.oid);\n\t\tif (root in grouped) {\n\t\t\tgrouped[root].push(patch);\n\t\t} else {\n\t\t\tgrouped[root] = [patch];\n\t\t}\n\t}\n\treturn grouped;\n}\n\nexport type NormalizedObject =\n\t| {\n\t\t\t[key: PropertyName]: PropertyValue;\n\t }\n\t| Array<PropertyValue>;\n\nfunction listCheck(obj: any, patch: OperationPatch): obj is Array<unknown> {\n\tif (!Array.isArray(obj)) {\n\t\tif (obj === undefined) {\n\t\t\tconsole.error(\n\t\t\t\t`Cannot apply list patch; expected array, received ${JSON.stringify(\n\t\t\t\t\tobj,\n\t\t\t\t)}. This suggests your data is changing from a list to an object over time. (OID: ${maybeGetOid(\n\t\t\t\t\tobj,\n\t\t\t\t)})\\nPatch that was not applied: ${JSON.stringify(patch)}`,\n\t\t\t);\n\t\t}\n\t\treturn false;\n\t} else {\n\t\treturn true;\n\t}\n}\n\n/**\n * The incoming object should already be normalized!\n * This function will mutate the base object.\n */\nexport function applyPatch<T extends NormalizedObject>(\n\tbase: T | undefined,\n\tpatch: OperationPatch,\n\t/**\n\t * Optionally supply a list to which any refs which\n\t * are removed during the patch will be appended.\n\t */\n\tdeletedRefs?: (FileRef | ObjectRef)[],\n): T | undefined {\n\t// deleted objects are represented by undefined\n\t// and remain deleted unless re-initialized\n\tif ((base === undefined || base === null) && patch.op !== 'initialize') {\n\t\treturn base;\n\t}\n\t// ditch typing internally.\n\tconst baseAsAny = base as any;\n\tlet index;\n\tlet spliceResult: any[];\n\n\t// a helper, pass it a value which is about\n\t// to be removed and it will append it to the list\n\t// if it was a ref\n\tfunction checkRef(field: any) {\n\t\t// don't bother if not supplied\n\t\tif (!deletedRefs) return;\n\t\tif (isRef(field)) {\n\t\t\tdeletedRefs.push(field);\n\t\t}\n\t}\n\n\tswitch (patch.op) {\n\t\tcase 'set':\n\t\t\tcheckRef(baseAsAny[patch.name]);\n\t\t\tbaseAsAny[patch.name] = patch.value;\n\t\t\tbreak;\n\t\tcase 'remove':\n\t\t\tcheckRef(baseAsAny[patch.name]);\n\t\t\tdelete baseAsAny[patch.name];\n\t\t\tbreak;\n\t\tcase 'list-set':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tcheckRef(base[patch.index]);\n\t\t\t\tbase[patch.index] = patch.value;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'list-push':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tbase.push(patch.value);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'list-delete':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tcheckRef(base[patch.index]);\n\t\t\t\tbase.splice(patch.index, patch.count);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'list-move-by-index':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tspliceResult = base.splice(patch.from, 1);\n\t\t\t\tbase.splice(patch.to, 0, spliceResult[0]);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'list-remove':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tdo {\n\t\t\t\t\tconst valueToRemove = patch.value;\n\t\t\t\t\tif (patch.only === 'last') {\n\t\t\t\t\t\tif (isRef(valueToRemove)) {\n\t\t\t\t\t\t\tindex = findLastIndex(\n\t\t\t\t\t\t\t\tbase,\n\t\t\t\t\t\t\t\t(item: any) => isRef(item) && compareRefs(item, valueToRemove),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tindex = base.lastIndexOf(valueToRemove);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (isRef(valueToRemove)) {\n\t\t\t\t\t\t\tindex = base.findIndex(\n\t\t\t\t\t\t\t\t(item: any) => isRef(item) && compareRefs(item, valueToRemove),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tindex = base.indexOf(valueToRemove);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (index !== -1) {\n\t\t\t\t\t\tcheckRef(base[index]);\n\t\t\t\t\t\tbase.splice(index, 1);\n\t\t\t\t\t}\n\t\t\t\t} while (!patch.only && index !== -1);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'list-add':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tconst alreadyHas = base.some((item: any) => {\n\t\t\t\t\tif (isObjectRef(item) && isObjectRef(patch.value)) {\n\t\t\t\t\t\treturn item.id === patch.value.id;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn item === patch.value;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (!alreadyHas) {\n\t\t\t\t\tbase.push(patch.value);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'list-move-by-ref':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tindex = base.findIndex((v) => compareRefs(v, patch.value));\n\t\t\t\tspliceResult = base.splice(index, 1);\n\t\t\t\tbase.splice(patch.index, 0, spliceResult[0]);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'list-insert':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tif (!patch.value && !patch.values) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Cannot apply list insert patch; expected value or values, received ${JSON.stringify(\n\t\t\t\t\t\t\tpatch,\n\t\t\t\t\t\t)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (patch.value) {\n\t\t\t\t\tbase.splice(patch.index, 0, patch.value);\n\t\t\t\t} else {\n\t\t\t\t\tbase.splice(patch.index, 0, ...patch.values!);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'delete':\n\t\t\t// collect all refs that are deleted\n\t\t\tif (Array.isArray(base)) {\n\t\t\t\tbase.forEach(checkRef);\n\t\t\t} else if (isObject(base)) {\n\t\t\t\tObject.values(base || {}).forEach(checkRef);\n\t\t\t}\n\t\t\treturn undefined;\n\t\tcase 'initialize':\n\t\t\treturn cloneDeep(patch.value);\n\t\tcase 'touch':\n\t\t\t// no-op\n\t\t\treturn base;\n\t\tdefault:\n\t\t\tthrow new Error(`Unsupported patch operation: ${(patch as any).op}`);\n\t}\n\treturn base;\n}\n\nexport function applyOperations<T extends NormalizedObject>(\n\tbase: T | undefined,\n\toperations: Operation[],\n\tdeletedRefs?: (ObjectRef | FileRef)[],\n\t/**\n\t * Provide and it will be assigned any authz info assigned\n\t * in applied operations\n\t */\n\tauthzRef?: { authz?: string },\n): T | undefined {\n\tlet cur = base as T | undefined;\n\tfor (const op of operations) {\n\t\tcur = applyPatch(cur, op.data, deletedRefs);\n\t\tif (authzRef && op.data.op === 'initialize' && op.authz) {\n\t\t\tauthzRef.authz = op.authz;\n\t\t}\n\t}\n\treturn cur;\n}\n\n/**\n * Mutates the original object in place. Returns all referenced\n * objects oids.\n */\nexport function substituteRefsWithObjects(\n\tbase: any,\n\trefs: Map<ObjectIdentifier, any>,\n\tused: ObjectIdentifier[] = [],\n): ObjectIdentifier[] {\n\tif (Array.isArray(base)) {\n\t\tfor (let i = 0; i < base.length; i++) {\n\t\t\tconst item = base[i];\n\t\t\tbase[i] = dereference(item, refs, used);\n\t\t\tif (isObject(base[i])) {\n\t\t\t\tsubstituteRefsWithObjects(base[i], refs, used);\n\t\t\t}\n\t\t}\n\t} else if (isFileRef(base)) {\n\t\t// don't do anything with file refs\n\t} else if (isObject(base)) {\n\t\t// not sure where to put this assertion but it's important to make\n\t\t// sure all nested objects include an OID\n\t\tassert(\n\t\t\tmaybeGetOid(base),\n\t\t\t`Object ${JSON.stringify(base)} must have an oid`,\n\t\t);\n\t\tfor (const key of Object.keys(base)) {\n\t\t\tbase[key] = dereference(base[key], refs, used);\n\n\t\t\t// now that objects are in place, recursively substitute\n\t\t\tif (isObject(base[key])) {\n\t\t\t\tsubstituteRefsWithObjects(base[key], refs, used);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn used;\n}\n\nfunction dereference(\n\tinput: any,\n\trefs: Map<ObjectIdentifier, any>,\n\tused: ObjectIdentifier[],\n): any {\n\tif (isObjectRef(input)) {\n\t\tused.push(input.id);\n\t\tconst resolved = refs.get(input.id);\n\t\tassert(!!resolved, `No value was found in object map for ${input.id}`);\n\t\treturn assignOid(resolved, input.id);\n\t} else {\n\t\treturn input;\n\t}\n}\n\nexport function substituteFirstLevelObjectsWithRefs<\n\tBase extends { [key: string]: any } | any[],\n>(\n\tbase: Base,\n\trefObjects: Map<ObjectIdentifier, any> = new Map(),\n): Map<ObjectIdentifier, any> {\n\tif (Array.isArray(base)) {\n\t\tfor (let i = 0; i < base.length; i++) {\n\t\t\tconst item = base[i];\n\t\t\t// special handling of file refs, which are treated like primitives\n\t\t\tif (isFileRef(item)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tassert(\n\t\t\t\t!isRef(item),\n\t\t\t\t'An object with refs was passed to substituteFirstLevelObjectsWithRefs, this is not allowed',\n\t\t\t);\n\t\t\tif (isObject(item)) {\n\t\t\t\tconst oid = getOid(item);\n\t\t\t\tbase[i] = {\n\t\t\t\t\t'@@type': 'ref',\n\t\t\t\t\tid: oid,\n\t\t\t\t};\n\t\t\t\trefObjects.set(oid, item);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor (const [key, value] of Object.entries(base)) {\n\t\t\t// special handling of file refs, which are treated like primitives\n\t\t\tif (isFileRef(value)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tassert(\n\t\t\t\t!isRef(value),\n\t\t\t\t'An object with refs was passed to substituteFirstLevelObjectsWithRefs, this is not allowed',\n\t\t\t);\n\t\t\tif (isObject(value)) {\n\t\t\t\tbase[key] = {\n\t\t\t\t\t'@@type': 'ref',\n\t\t\t\t\tid: getOid(value),\n\t\t\t\t};\n\n\t\t\t\trefObjects.set(getOid(value), value);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn refObjects;\n}\n\n/**\n * Takes a snapshot with applied OIDs and deconstructs it entirely\n * into individual objects with ref fields. Populates the supplied\n * map with the final objects.\n */\nexport function deconstructSnapshotToRefs(\n\tsnapshot: any,\n\trefTargets: Map<ObjectIdentifier, any>,\n) {\n\tif (typeof snapshot !== 'object') {\n\t\treturn;\n\t}\n\trefTargets.set(getOid(snapshot), snapshot);\n\tconst thisLevelOfTargets = substituteFirstLevelObjectsWithRefs(snapshot);\n\tfor (const [oid, obj] of thisLevelOfTargets.entries()) {\n\t\trefTargets.set(oid, obj);\n\t\tdeconstructSnapshotToRefs(obj, refTargets);\n\t}\n}\n\nexport function operationSupersedes(op: Operation): PropertyName | boolean {\n\t// todo: add 'remove'\n\tif (op.data.op === 'set') {\n\t\treturn op.data.name;\n\t}\n\n\treturn false;\n}\n\n/**\n * Determine if an operation is superseded by a set of supersession values\n * provided by operationSupersedes. Assumes the operation OID matches\n * already.\n */\nexport function isSuperseded(\n\top: Operation,\n\tsupersession: Set<PropertyName | boolean>,\n) {\n\tif (supersession.has(true)) {\n\t\treturn true;\n\t} else if (op.data.op === 'set' || op.data.op === 'remove') {\n\t\treturn supersession.has(op.data.name);\n\t}\n\n\treturn false;\n}\n\n/**\n * Allocates a copy with only valid keys for transmitting over\n * the protocol. TODO: make this unnecessary or evaluate if it's\n * worth it to do.\n */\nexport function pickValidOperationKeys(operation: Operation): Operation {\n\treturn {\n\t\toid: operation.oid,\n\t\ttimestamp: operation.timestamp,\n\t\tdata: operation.data,\n\t\tauthz: operation.authz,\n\t};\n}\n", "import { v4 } from 'uuid';\nimport { isFileRef } from './files.js';\nimport { isObjectRef, ObjectRef } from './operation.js';\nimport { isRef } from './refs.js';\nimport { assert, isObject, safeStringify } from './utils.js';\n\n/**\n * OIDs\n *\n * OIDs are used to identify objects in the document. They also encode\n * information about the object useful to identifying an object found\n * on its own and associating it back to its parent.\n *\n * An OID is structured as such:\n * <collection>/<root id>:<random>\n *\n * OIDs have a few characteristics:\n * - They include the collection name of the parent document\n * - They include the primary key of the parent document\n * - They may include a random sequence to identify sub-objects\n *\n * Collection name and document key are used to link any isolated\n * object back to its parent document.\n *\n * The random sequence allows the application to encode different\n * identities for objects at the same position in a document for\n * conflict resolution purposes\n */\n\nexport type ObjectIdentifier = string;\n\nconst SEGMENT_SEPARATOR = '/';\nconst RANDOM_SEPARATOR = ':';\n\n/**\n * This is the global, in-memory storage for all OIDs. It is used to\n * associate JS objects with OIDs without modifying the objects themselves.\n */\nconst oidMap = new WeakMap<any, ObjectIdentifier>();\n\nexport function getOid(obj: any) {\n\tconst oid = maybeGetOid(obj);\n\tassert(\n\t\t!!oid,\n\t\t`Object ${safeStringify(obj)} does not have an OID assigned to it`,\n\t);\n\treturn oid;\n}\n\nexport function maybeGetOid(obj: any): ObjectIdentifier | undefined {\n\tif (!isObject(obj)) {\n\t\treturn undefined;\n\t}\n\treturn oidMap.get(obj);\n}\n\nexport function assignOid(obj: any, oid: ObjectIdentifier) {\n\tassert(\n\t\tisObject(obj),\n\t\t`Only objects can be assigned OIDs, received ${safeStringify(obj)}`,\n\t);\n\tif (hasOid(obj)) {\n\t\tremoveOid(obj);\n\t}\n\toidMap.set(obj, oid);\n\treturn obj;\n}\n\nexport function hasOid(obj: any) {\n\treturn !!maybeGetOid(obj);\n}\n\nexport function removeOid(obj: any) {\n\toidMap.delete(obj);\n\treturn obj;\n}\n\n/**\n * For sub-objects, assign a random sub-OID if no OID\n * is already assigned.\n */\nexport function ensureOid(\n\tobj: any,\n\trootOid: ObjectIdentifier,\n\tcreateSubId?: () => string,\n) {\n\tif (!hasOid(obj)) {\n\t\tconst oid = createSubOid(rootOid, createSubId);\n\t\tassignOid(obj, oid);\n\t\treturn oid;\n\t} else {\n\t\treturn getOid(obj);\n\t}\n}\n\nexport function ensureCompatibleOid(\n\tobj: any,\n\trootOid: ObjectIdentifier,\n\tcreateSubId?: () => string,\n) {\n\tif (!hasOid(obj)) {\n\t\tconst oid = createSubOid(rootOid, createSubId);\n\t\tassignOid(obj, oid);\n\t\treturn oid;\n\t} else {\n\t\tconst existingOid = getOid(obj);\n\t\tif (!areOidsRelated(existingOid, rootOid)) {\n\t\t\tconst oid = createSubOid(rootOid, createSubId);\n\t\t\tassignOid(obj, oid);\n\t\t\treturn oid;\n\t\t} else {\n\t\t\treturn getOid(obj);\n\t\t}\n\t}\n}\n\nconst SANITIZE_PLACEHOLDERS = {\n\t'.': '˙',\n\t'/': '&slash;',\n\t':': ':',\n};\nfunction sanitizeFragment(id: string) {\n\t// replaces separator characters with placeholders\n\treturn id\n\t\t.replace(/[/]/g, SANITIZE_PLACEHOLDERS['/'])\n\t\t.replace(/[:]/g, SANITIZE_PLACEHOLDERS[':'])\n\t\t.replace(/[.]/g, SANITIZE_PLACEHOLDERS['.']);\n}\nfunction unsanitizeFragment(id: string) {\n\t// replaces placeholders with separator characters\n\treturn id\n\t\t.replace(/&slash;/g, '/')\n\t\t.replace(/:/g, ':')\n\t\t.replace(/˙/g, '.');\n}\n\n/**\n * Creates an OID for the document with a particular ID.\n * To create a sub-object OID, use createSubOid and pass\n * the root OID.\n */\nexport function createOid(\n\tcollection: string,\n\tdocumentId: string,\n\tsubId?: string,\n) {\n\tlet oid =\n\t\tsanitizeFragment(collection) +\n\t\tSEGMENT_SEPARATOR +\n\t\tsanitizeFragment(documentId);\n\tif (subId) {\n\t\toid += RANDOM_SEPARATOR + subId;\n\t}\n\treturn oid;\n}\n\nexport function createSubOid(\n\troot: ObjectIdentifier,\n\tcreateSubId: () => string = createOidSubId,\n) {\n\tconst { collection, id } = decomposeOid(root);\n\treturn createOid(collection, id, createSubId());\n}\n\nexport function decomposeOid(oid: ObjectIdentifier): {\n\tcollection: string;\n\tid: string;\n\tsubId?: string;\n} {\n\tlet [collection, coreId, ...others] = oid.split('/');\n\t// if 'others' exists, something's off, but maybe we can recover...\n\t// by assuming the last segment is the authz and bolting the rest onto coreId\n\tif (others.length) {\n\t\tconsole.error(\n\t\t\t`OID ${oid} has more than 3 segments. Attempting to parse it anyway.`,\n\t\t);\n\t\tcoreId += '/' + others.join('/');\n\t}\n\n\tconst [idOrLegacyPathId, random] = coreId.split(RANDOM_SEPARATOR);\n\n\tlet id;\n\t// legacy path handling. shouldn't be necessary anymore.\n\tif (idOrLegacyPathId.includes('.')) {\n\t\tid = idOrLegacyPathId.slice(0, idOrLegacyPathId.indexOf('.'));\n\t} else {\n\t\tid = idOrLegacyPathId;\n\t}\n\n\treturn {\n\t\tcollection: unsanitizeFragment(collection),\n\t\tid: unsanitizeFragment(id),\n\t\tsubId: random,\n\t};\n}\n\nexport function assertAllLevelsHaveOids(obj: any, root?: any) {\n\tassert(\n\t\tgetOid(obj),\n\t\t`Object ${safeStringify(obj)} must have an oid (child of ${safeStringify(\n\t\t\troot,\n\t\t)})`,\n\t);\n\tif (Array.isArray(obj)) {\n\t\tfor (const item of obj) {\n\t\t\tassertAllLevelsHaveOids(item, root || obj);\n\t\t}\n\t} else if (isObject(obj)) {\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tassertAllLevelsHaveOids(obj[key], root || obj);\n\t\t}\n\t}\n}\n\nexport function assignOidsToAllSubObjects(\n\tobj: any,\n\tcreateSubId?: () => string,\n) {\n\tconst rootOid = getOid(obj);\n\tif (Array.isArray(obj)) {\n\t\tlet item;\n\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\titem = obj[i];\n\t\t\tif (isObject(item) && !isRef(item)) {\n\t\t\t\tensureCompatibleOid(item, rootOid, createSubId);\n\t\t\t\tassignOidsToAllSubObjects(item, createSubId);\n\t\t\t}\n\t\t}\n\t} else if (isObject(obj) && !isRef(obj)) {\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tif (isObject(obj[key]) && !isRef(obj[key])) {\n\t\t\t\tensureCompatibleOid(obj[key], rootOid, createSubId);\n\t\t\t\tassignOidsToAllSubObjects(obj[key], createSubId);\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport function removeOidsFromAllSubObjects(obj: any) {\n\tremoveOid(obj);\n\n\tif (Array.isArray(obj)) {\n\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\tremoveOidsFromAllSubObjects(obj[i]);\n\t\t}\n\t} else if (isObject(obj)) {\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tremoveOidsFromAllSubObjects(obj[key]);\n\t\t}\n\t}\n}\n\nexport function createOidSubId() {\n\treturn v4().slice(0, 8);\n}\n\nexport function createRef(oid: ObjectIdentifier): ObjectRef {\n\treturn {\n\t\t'@@type': 'ref',\n\t\tid: oid,\n\t};\n}\n\nexport function normalize(\n\tobj: any,\n\trefs: Map<ObjectIdentifier, any> = new Map(),\n): Map<ObjectIdentifier, any> {\n\tif (Array.isArray(obj)) {\n\t\tconst oid = getOid(obj);\n\t\tconst copy = assignOid([], oid);\n\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\tconst value = obj[i];\n\t\t\tif (isObject(value)) {\n\t\t\t\tif (isObjectRef(value)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'An attempt was made to normalize an already normalized object! This is an error in verdant itself.',\n\t\t\t\t\t);\n\t\t\t\t} else if (isFileRef(value)) {\n\t\t\t\t\tcopy[i] = value;\n\t\t\t\t\tcontinue;\n\t\t\t\t} else {\n\t\t\t\t\tconst itemOid = getOid(value);\n\t\t\t\t\tcopy[i] = createRef(itemOid);\n\t\t\t\t\tnormalize(value, refs);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcopy[i] = value;\n\t\t\t}\n\t\t}\n\t\trefs.set(oid, copy);\n\t} else if (isObject(obj) && !isRef(obj)) {\n\t\tconst oid = getOid(obj);\n\t\tconst copy = assignOid({} as Record<string, any>, oid);\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tconst value = obj[key];\n\t\t\tif (isObject(value)) {\n\t\t\t\tif (isObjectRef(value)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'An attempt was made to normalize an already normalized object! This is an error in verdant itself.',\n\t\t\t\t\t);\n\t\t\t\t} else if (isFileRef(value)) {\n\t\t\t\t\t// stop here\n\t\t\t\t\tcopy[key] = value;\n\t\t\t\t} else {\n\t\t\t\t\tconst itemOid = getOid(value);\n\t\t\t\t\tcopy[key] = createRef(itemOid);\n\t\t\t\t\tnormalize(value, refs);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcopy[key] = value;\n\t\t\t}\n\t\t}\n\t\trefs.set(oid, copy);\n\t} else if (isRef(obj)) {\n\t}\n\treturn refs;\n}\n\n/**\n * Only normalizes direct children. The created map\n * of objects will still have nested objects.\n */\nexport function normalizeFirstLevel(obj: any) {\n\tconst refs = new Map<ObjectIdentifier, any>();\n\tconst oidKeyPairs = new Map<ObjectIdentifier, string | number>();\n\tif (Array.isArray(obj)) {\n\t\tconst oid = getOid(obj);\n\t\tconst copy = assignOid([], oid);\n\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\tconst value = obj[i];\n\t\t\tif (isObject(value)) {\n\t\t\t\tconst itemOid = getOid(value);\n\t\t\t\tcopy[i] = createRef(itemOid);\n\t\t\t\trefs.set(itemOid, value);\n\t\t\t\toidKeyPairs.set(itemOid, i);\n\t\t\t} else {\n\t\t\t\tcopy[i] = value;\n\t\t\t}\n\t\t}\n\t\trefs.set(oid, copy);\n\t} else if (isObject(obj)) {\n\t\tconst oid = getOid(obj);\n\t\tconst copy = assignOid({} as Record<string, any>, oid);\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tconst value = obj[key];\n\t\t\tif (isObject(value)) {\n\t\t\t\tconst itemOid = getOid(value);\n\t\t\t\tcopy[key] = createRef(itemOid);\n\t\t\t\trefs.set(itemOid, value);\n\t\t\t\toidKeyPairs.set(itemOid, key);\n\t\t\t} else {\n\t\t\t\tcopy[key] = value;\n\t\t\t}\n\t\t}\n\t\trefs.set(oid, copy);\n\t}\n\treturn { refs, oidKeyPairs };\n}\n\nexport function getOidRoot(oid: ObjectIdentifier) {\n\treturn oid.split('.')[0].split(RANDOM_SEPARATOR)[0];\n}\n\n/**\n * Returns an inclusive range of OIDs that represent\n * all of an OID's possible sub-objects.\n */\nexport function getOidSubIdRange(oid: ObjectIdentifier) {\n\tconst root = getOidRoot(oid);\n\tconst lastSubId = createSubOid(root, () => '\\uffff');\n\treturn [`${root}${RANDOM_SEPARATOR}`, lastSubId];\n}\n\nexport function getRoots(oids: ObjectIdentifier[]) {\n\tconst set = new Set<ObjectIdentifier>();\n\tfor (const oid of oids) {\n\t\tset.add(getOidRoot(oid));\n\t}\n\treturn Array.from(set);\n}\n\nexport function areOidsRelated(oidA: ObjectIdentifier, oidB: ObjectIdentifier) {\n\treturn getOidRoot(oidA) === getOidRoot(oidB);\n}\n\nexport function isRootOid(oid: ObjectIdentifier) {\n\treturn !oid.includes(RANDOM_SEPARATOR);\n}\n\n/**\n * Recursively rewrites any OIDs in an object which are 'foreign' -\n * i.e. relate to some other object/entity - to be local to the\n * current object. This is deterministic, so it can be done\n * on multiple clients independently with predictable results.\n */\nexport function fixForeignOids(obj: any) {\n\tconst oid = maybeGetOid(obj);\n\tif (!oid) return;\n\n\tif (Array.isArray(obj)) {\n\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\tmigrateForeignOid(oid, obj[i]);\n\t\t\tfixForeignOids(obj[i]);\n\t\t}\n\t} else if (isObject(obj)) {\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tmigrateForeignOid(oid, obj[key]);\n\t\t\tfixForeignOids(obj[key]);\n\t\t}\n\t}\n}\n\nfunction migrateForeignOid(parentOid: ObjectIdentifier, child: any) {\n\tconst childOid = maybeGetOid(child);\n\tif (childOid && !areOidsRelated(parentOid, childOid)) {\n\t\tconst { subId, id } = decomposeOid(childOid);\n\t\t// reuse existing subId. if child is a foreign root, use its id as subId\n\t\tassignOid(\n\t\t\tchild,\n\t\t\tcreateSubOid(parentOid, () => subId || id),\n\t\t);\n\t}\n}\n\n/**\n * Returns a list of all OIDs assigned to this object\n * and all sub-objects.\n */\nexport function getAllOids(root: any) {\n\tconst oids = new Set<ObjectIdentifier>();\n\tconst stack = [root];\n\twhile (stack.length) {\n\t\tconst obj = stack.pop();\n\t\tconst oid = maybeGetOid(obj);\n\t\tif (oid) {\n\t\t\toids.add(oid);\n\t\t}\n\t\tif (Array.isArray(obj)) {\n\t\t\tstack.push(...obj);\n\t\t} else if (isObject(obj)) {\n\t\t\tstack.push(...Object.values(obj));\n\t\t}\n\t}\n\treturn Array.from(oids);\n}\n", "import {\n\tassignOid,\n\tcreateOid,\n\tdecomposeOid,\n\tgetOidRoot,\n\tObjectIdentifier,\n} from './oids.js';\nimport { isObject } from './utils.js';\n\nexport const LEGACY_OID_KEY = '__@@oid_do_not_use';\nexport const OID_KEY = '@@id';\n\nexport function maybeGetOidProperty(obj: any) {\n\tif (!isObject(obj)) {\n\t\treturn undefined;\n\t}\n\treturn obj[OID_KEY] || obj[LEGACY_OID_KEY];\n}\n\nfunction removeOidProperty(obj: any) {\n\tif (!isObject(obj)) {\n\t\treturn obj;\n\t}\n\tdelete obj[LEGACY_OID_KEY];\n\tdelete obj[OID_KEY];\n\treturn obj;\n}\n\nfunction copyOidFromPropertyToSystem(obj: any) {\n\tconst oid = maybeGetOidProperty(obj);\n\tif (oid) {\n\t\tassignOid(obj, oid);\n\t}\n}\n\n/**\n *\n * Removes the special property from all objects in the given object\n * which have an OID, transferring the OID from the property to the OID\n * system in-memory.\n */\nexport function removeOidPropertiesFromAllSubObjects(obj: any) {\n\tcopyOidFromPropertyToSystem(obj);\n\tremoveOidProperty(obj);\n\n\tif (Array.isArray(obj)) {\n\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\tremoveOidPropertiesFromAllSubObjects(obj[i]);\n\t\t}\n\t} else if (isObject(obj)) {\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tremoveOidPropertiesFromAllSubObjects(obj[key]);\n\t\t}\n\t}\n}\n\nexport function isLegacyDotOid(oid: ObjectIdentifier) {\n\tconst partBeforeRandomSep = oid.split(':')[0];\n\treturn partBeforeRandomSep.includes('.');\n}\n\nexport function convertLegacyOid(oid: ObjectIdentifier) {\n\tconst { collection, id, subId } = decomposeOid(oid);\n\treturn createOid(collection, id, subId);\n}\n\n// NOTE: all legacy OIDs should now be gone.\nexport const MATCH_LEGACY_OID_JSON_STRING = /\"\\w+\\/[^\"]+?(\\.[^\"]+)+\\:[\\S]+?\"/g;\nexport function replaceLegacyOidsInJsonString(string: string) {\n\t// replace every match of a legacy OID, converting to a new OID\n\treturn string.replaceAll(MATCH_LEGACY_OID_JSON_STRING, (match) => {\n\t\tconst legacyOid = match.slice(1, match.length - 1);\n\t\treturn `\"${convertLegacyOid(legacyOid)}\"`;\n\t});\n}\nexport function replaceLegacyOidsInObject(obj: any) {\n\treturn JSON.parse(replaceLegacyOidsInJsonString(JSON.stringify(obj)));\n}\n\nexport function getLegacyDotOidSubIdRange(oid: ObjectIdentifier) {\n\tconst root = getOidRoot(oid);\n\treturn [`${root}.`, `${root}.\\uffff`];\n}\n\nexport function isOidKey(key: string) {\n\treturn key === OID_KEY || key === LEGACY_OID_KEY;\n}\n", "/**\n * High-level patch creation for use with complex nested objects.\n */\n\nimport { AuthorizationKey } from './authz.js';\nimport { diffToPatches } from './diffing.js';\nimport { FileRef } from './files.js';\nimport { createRef, createSubOid, ObjectIdentifier } from './oids.js';\nimport {\n\tinitialToPatches,\n\tObjectRef,\n\tOperation,\n\tPropertyName,\n\tPropertyValue,\n\tshallowInitialToPatches,\n} from './operation.js';\nimport { isRef } from './refs.js';\nimport { assert, isObject } from './utils.js';\n\nexport class PatchCreator {\n\tconstructor(\n\t\treadonly getNow: () => string,\n\t\treadonly createSubId?: () => string,\n\t) {}\n\n\tisPrimitive = (value: any) => {\n\t\treturn !isObject(value) || isRef(value);\n\t};\n\n\tcreateDiff = (\n\t\tfrom: any,\n\t\tto: any,\n\t\toptions: {\n\t\t\tmergeUnknownObjects?: boolean;\n\t\t\t/** @deprecated use the equivalent 'merge' */\n\t\t\tdefaultUndefined?: boolean;\n\t\t\tmerge?: boolean;\n\t\t\tauthz?: AuthorizationKey;\n\t\t} = {},\n\t) => {\n\t\treturn diffToPatches(from, to, this.getNow, this.createSubId, [], options);\n\t};\n\n\tcreateInitialize = (\n\t\tobj: any,\n\t\toid: ObjectIdentifier,\n\t\tauthz?: AuthorizationKey,\n\t\tshallow?: boolean,\n\t) => {\n\t\tif (shallow) {\n\t\t\treturn shallowInitialToPatches(\n\t\t\t\tobj,\n\t\t\t\toid,\n\t\t\t\tthis.getNow,\n\t\t\t\tundefined,\n\t\t\t\tauthz ? { authz } : undefined,\n\t\t\t);\n\t\t}\n\t\treturn initialToPatches(\n\t\t\tobj,\n\t\t\toid,\n\t\t\tthis.getNow,\n\t\t\tthis.createSubId,\n\t\t\tundefined,\n\t\t\tauthz ? { authz } : undefined,\n\t\t);\n\t};\n\n\tcreateSet = (\n\t\toid: ObjectIdentifier,\n\t\tkey: PropertyName,\n\t\tvalue: any,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\t// incoming value must be normalized. if it's not a primitive, it and all sub-objects\n\t\t// must be created\n\t\tif (this.isPrimitive(value)) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'set',\n\t\t\t\t\t\tname: key,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t} else {\n\t\t\tconst itemOid = createSubOid(oid, this.createSubId);\n\t\t\treturn [\n\t\t\t\t// since we're setting a complex nested object, we can initialize it wholesale.\n\t\t\t\t// no diffing to do.\n\t\t\t\t...initialToPatches(\n\t\t\t\t\tvalue,\n\t\t\t\t\titemOid,\n\t\t\t\t\tthis.getNow,\n\t\t\t\t\tthis.createSubId,\n\t\t\t\t\tundefined,\n\t\t\t\t\t{\n\t\t\t\t\t\tauthz,\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\t// then set the reference to the object\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'set',\n\t\t\t\t\t\tvalue: createRef(itemOid),\n\t\t\t\t\t\tname: key,\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t};\n\n\tcreateRemove = (\n\t\toid: ObjectIdentifier,\n\t\tkey: PropertyName,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\treturn [\n\t\t\t{\n\t\t\t\toid,\n\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\tdata: {\n\t\t\t\t\top: 'remove',\n\t\t\t\t\tname: key,\n\t\t\t\t},\n\t\t\t\tauthz,\n\t\t\t},\n\t\t];\n\t};\n\n\tcreateListSet = (\n\t\toid: ObjectIdentifier,\n\t\tindex: number,\n\t\tvalue: any,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tassert(index >= 0, 'List index must be non-negative');\n\t\tif (this.isPrimitive(value)) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-set',\n\t\t\t\t\t\tindex,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t} else {\n\t\t\tconst itemOid = createSubOid(oid, this.createSubId);\n\t\t\treturn [\n\t\t\t\t...initialToPatches(\n\t\t\t\t\tvalue,\n\t\t\t\t\titemOid,\n\t\t\t\t\tthis.getNow,\n\t\t\t\t\tthis.createSubId,\n\t\t\t\t\tundefined,\n\t\t\t\t\t{\n\t\t\t\t\t\tauthz,\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-set',\n\t\t\t\t\t\tindex,\n\t\t\t\t\t\tvalue: createRef(itemOid),\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t};\n\n\tcreateListPush = (\n\t\toid: ObjectIdentifier,\n\t\tvalue: any,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tif (this.isPrimitive(value)) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-push',\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t} else {\n\t\t\tconst itemOid = createSubOid(oid, this.createSubId);\n\t\t\treturn [\n\t\t\t\t...initialToPatches(value, itemOid, this.getNow, undefined, undefined, {\n\t\t\t\t\tauthz,\n\t\t\t\t}),\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-push',\n\t\t\t\t\t\tvalue: createRef(itemOid),\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t};\n\n\tcreateListAdd = (\n\t\toid: ObjectIdentifier,\n\t\tvalue: any,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tif (!this.isPrimitive(value)) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-add',\n\t\t\t\t\t\tvalue: createRef(value),\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t} else {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-add',\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t};\n\n\tcreateListInsert = (\n\t\toid: ObjectIdentifier,\n\t\tindex: number,\n\t\tvalue: any,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tassert(index >= 0, 'List index must be non-negative');\n\t\tif (this.isPrimitive(value)) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-insert',\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\tindex,\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t} else {\n\t\t\tconst itemOid = createSubOid(oid, this.createSubId);\n\t\t\treturn [\n\t\t\t\t...initialToPatches(\n\t\t\t\t\tvalue,\n\t\t\t\t\titemOid,\n\t\t\t\t\tthis.getNow,\n\t\t\t\t\tthis.createSubId,\n\t\t\t\t\tundefined,\n\t\t\t\t\tauthz\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tauthz,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: undefined,\n\t\t\t\t),\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-insert',\n\t\t\t\t\t\tvalue: createRef(itemOid),\n\t\t\t\t\t\tindex,\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t};\n\n\tcreateListInsertMany = (\n\t\toid: ObjectIdentifier,\n\t\tindex: number,\n\t\tvalues: any[],\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tassert(index >= 0, 'List index must be non-negative');\n\t\tconst operations: Operation[] = [];\n\t\tconst refs = values.map((value) => {\n\t\t\tif (this.isPrimitive(value)) return value;\n\t\t\tconst subOid = createSubOid(oid, this.createSubId);\n\t\t\toperations.push(\n\t\t\t\t...initialToPatches(\n\t\t\t\t\tvalue,\n\t\t\t\t\tsubOid,\n\t\t\t\t\tthis.getNow,\n\t\t\t\t\tthis.createSubId,\n\t\t\t\t\tundefined,\n\t\t\t\t\t{\n\t\t\t\t\t\tauthz,\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn createRef(subOid);\n\t\t});\n\t\toperations.push({\n\t\t\toid,\n\t\t\ttimestamp: this.getNow(),\n\t\t\tdata: {\n\t\t\t\top: 'list-insert',\n\t\t\t\tvalues: refs,\n\t\t\t\tindex,\n\t\t\t},\n\t\t\tauthz,\n\t\t});\n\t\treturn operations;\n\t};\n\n\tcreateListRemove = (\n\t\toid: ObjectIdentifier,\n\t\tvalue: PropertyValue,\n\t\tonly?: 'first' | 'last',\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\treturn [\n\t\t\t{\n\t\t\t\toid,\n\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\tdata: {\n\t\t\t\t\top: 'list-remove',\n\t\t\t\t\tvalue,\n\t\t\t\t\tonly,\n\t\t\t\t},\n\t\t\t\tauthz,\n\t\t\t},\n\t\t];\n\t};\n\n\tcreateListDelete = (\n\t\toid: ObjectIdentifier,\n\t\tindex: number,\n\t\tcount: number = 1,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tassert(index >= 0, 'List index must be non-negative');\n\t\tassert(count > 0, 'Count must be positive and non-zero');\n\t\treturn [\n\t\t\t{\n\t\t\t\toid,\n\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\tdata: {\n\t\t\t\t\top: 'list-delete',\n\t\t\t\t\tindex,\n\t\t\t\t\tcount,\n\t\t\t\t},\n\t\t\t\tauthz,\n\t\t\t},\n\t\t];\n\t};\n\n\tcreateListMoveByRef = (\n\t\toid: ObjectIdentifier,\n\t\tvalue: ObjectRef | FileRef,\n\t\tindex: number,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tassert(index >= 0, 'List index must be non-negative');\n\t\treturn [\n\t\t\t{\n\t\t\t\toid,\n\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\tdata: {\n\t\t\t\t\top: 'list-move-by-ref',\n\t\t\t\t\tvalue,\n\t\t\t\t\tindex,\n\t\t\t\t},\n\t\t\t\tauthz,\n\t\t\t},\n\t\t];\n\t};\n\n\tcreateListMoveByIndex = (\n\t\toid: ObjectIdentifier,\n\t\tfromIndex: number,\n\t\ttoIndex: number,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tassert(fromIndex >= 0, 'List move from index must be non-negative');\n\t\tassert(toIndex >= 0, 'List move to index must be non-negative');\n\t\treturn [\n\t\t\t{\n\t\t\t\toid,\n\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\tdata: {\n\t\t\t\t\top: 'list-move-by-index',\n\t\t\t\t\tfrom: fromIndex,\n\t\t\t\t\tto: toIndex,\n\t\t\t\t},\n\t\t\t\tauthz,\n\t\t\t},\n\t\t];\n\t};\n\n\tcreateDelete = (\n\t\toid: ObjectIdentifier,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\treturn [\n\t\t\t{\n\t\t\t\toid,\n\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\tdata: {\n\t\t\t\t\top: 'delete',\n\t\t\t\t},\n\t\t\t\tauthz,\n\t\t\t},\n\t\t];\n\t};\n\n\tcreateDeleteAll = (\n\t\toids: ObjectIdentifier[],\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\treturn oids.map((oid) => ({\n\t\t\toid,\n\t\t\ttimestamp: this.getNow(),\n\t\t\tdata: {\n\t\t\t\top: 'delete',\n\t\t\t},\n\t\t\tauthz,\n\t\t}));\n\t};\n}\n", "import { AuthorizationKey } from './authz.js';\nimport { VerdantError } from './error.js';\nimport {\n\tareOidsRelated,\n\tassignOid,\n\tcreateRef,\n\tgetOid,\n\tmaybeGetOid,\n\tObjectIdentifier,\n} from './oids.js';\nimport { isOidKey } from './oidsLegacy.js';\nimport { Operation } from './operation.js';\nimport { PatchCreator } from './patch.js';\nimport { compareRefs, isRef } from './refs.js';\nimport { cloneDeep, isObject } from './utils.js';\n\nexport type DiffContext = {\n\tpatches: Operation[];\n\t/**\n\t * If an object is merged with another and the new one does not\n\t * have an OID assigned, assume it is the same identity as previous\n\t */\n\tmergeUnknownObjects?: boolean;\n\t/**\n\t * If an incoming value is not assigned on the new object, use the previous value.\n\t * If false, undefined properties will erase the previous value.\n\t */\n\tmerge?: boolean;\n\t/**\n\t * Authorization to apply to all created operations\n\t */\n\tauthz?: AuthorizationKey;\n\tpatchCreator: PatchCreator;\n};\n\n/**\n * Compares two anythings and determines if they\n * represent the same thing. Works for primitives,\n * refs, and objects with OIDs.\n */\nfunction areTheSameIdentity(a: any, b: any) {\n\tif (a === b) return true;\n\tif (isRef(a) && isRef(b)) return compareRefs(a, b);\n\tconst aOid = maybeGetOid(a);\n\tconst bOid = maybeGetOid(b);\n\tif (aOid && bOid && aOid === bOid) return true;\n\treturn false;\n}\n\n/**\n * Enforces OID rules on subobjects being added to an entity.\n * - Every sub-object must have an OID\n * - The sub-object's OID must relate to the parent OID\n */\nfunction enforceAssignedOid(\n\tparentOid: ObjectIdentifier,\n\tnewObject: any,\n\texistingObjectOid: ObjectIdentifier | undefined,\n\tctx: DiffContext,\n) {\n\tif (!isDiffableObject(newObject)) {\n\t\t// nothing to do, the new value cannot have an oid as it is not\n\t\t// a sub-object.\n\t\treturn newObject;\n\t}\n\n\tconst oid = maybeGetOid(newObject);\n\tif (!oid) {\n\t\t// if merge unknown objects is enabled, we can assume the new object is the same\n\t\t// as the existing object (if present) and use its oid. otherwise we assign a new one.\n\t\tif (ctx.mergeUnknownObjects && existingObjectOid) {\n\t\t\tassignOid(newObject, existingObjectOid);\n\t\t}\n\t\t// NOTE: new OID assignments are done in patchCreator.\n\t} else if (!areOidsRelated(parentOid, oid)) {\n\t\t// when there's any doubt, clone the whole object. false -> do not copy OIDs\n\t\tconst clone = cloneDeep(newObject, false);\n\t\t// NOTE: new OID assignments are done in patchCreator.\n\t\treturn clone;\n\t}\n\treturn newObject;\n}\n\nfunction isDiffableObject(val: any) {\n\treturn isObject(val) && !isRef(val);\n}\n\nexport function diffToPatches(\n\tfrom: any,\n\tto: any,\n\tgetNow: () => string,\n\tcreateSubId?: () => string,\n\t_?: any, // legacy, TODO: remove\n\toptions?: {\n\t\tmergeUnknownObjects?: boolean;\n\t\tmerge?: boolean;\n\t\t/** @deprecated - use 'merge' */\n\t\tdefaultUndefined?: boolean;\n\t\tauthz?: AuthorizationKey;\n\t},\n) {\n\tconst ctx: DiffContext = {\n\t\tpatches: [],\n\t\tmergeUnknownObjects: options?.mergeUnknownObjects,\n\t\tmerge: options?.merge ?? options?.defaultUndefined,\n\t\tauthz: options?.authz,\n\t\tpatchCreator: new PatchCreator(getNow, createSubId),\n\t};\n\tdiff(from, to, ctx);\n\treturn ctx.patches;\n}\n\nexport function diff(from: any, to: any, ctx: DiffContext) {\n\tif (Array.isArray(from) && Array.isArray(to)) {\n\t\tdiffLists(from, to, ctx);\n\t} else if (Array.isArray(from) || Array.isArray(to)) {\n\t\tthrow new VerdantError(\n\t\t\tVerdantError.Code.Unexpected,\n\t\t\tundefined,\n\t\t\t'Cannot diff between array and non-array',\n\t\t);\n\t} else if (isDiffableObject(from) && isDiffableObject(to)) {\n\t\tdiffObjects(from, to, ctx);\n\t}\n}\n\n/**\n * Deep diff lists of any kind of item. Adds patches for the changes\n * to the context patch list.\n * @param from - the original list snapshot. must be the full snapshot, no references.\n * @param to - the new list snapshot. must be the full snapshot, no references.\n * @param ctx - the diff context to add patches to.\n */\nexport function diffLists(from: any[], to: any[], ctx: DiffContext) {\n\t// from object must be registered with an OID.\n\tconst oid = getOid(from);\n\t// this copy will be mutated to align with inserts, making things easier to compare.\n\tconst fromCopy = [];\n\t// while iterating from, also collect some metadata.\n\tconst oidsInFrom = new Set();\n\tfor (let i = 0; i < from.length; i++) {\n\t\tconst value = from[i];\n\t\tfromCopy[i] = value;\n\t\tconst oid = maybeGetOid(value);\n\t\tif (oid) {\n\t\t\toidsInFrom.add(oid);\n\t\t}\n\t}\n\n\t// first, normalize incoming data according to OID rules. this is done early\n\t// so future equality checks are according to configuration like mergeUnknownObjects.\n\t// for example, if a bare (no oid) object is supplied for an item and mergeUnknownObjects\n\t// is set, this will assign it the same OID as the existing item at that index, so it will\n\t// pass equality checks for insertion range, etc.\n\tfor (let i = 0; i < to.length; i++) {\n\t\tconst value = to[i];\n\t\tconst oldValue = from[i];\n\t\tto[i] = enforceAssignedOid(oid, value, maybeGetOid(oldValue), ctx);\n\t}\n\n\t// track whether the new list has gaps in it. a gap\n\t// means we can no longer use list-push for new items.\n\tlet noGaps = true;\n\t// track any items we move by reference, so we remember to\n\t// not delete them later.\n\tconst movedItems = new Set<ObjectIdentifier>();\n\tconst overwrittenItems = new Set<ObjectIdentifier>();\n\tfor (let i = 0; i < to.length; i++) {\n\t\tconst value = to[i];\n\t\tconst oldValue = fromCopy[i];\n\t\tif (value === undefined) {\n\t\t\tnoGaps = false;\n\t\t}\n\t\tconst itemOid = maybeGetOid(value);\n\n\t\t// we decide if this item is being added to the end of the list if:\n\t\t// - there were no empty spaces before it in the new list\n\t\t// - the index is beyond the scope of the original list.\n\t\t// the second condition is carefully selected since it accounts for\n\t\t// the prior list having gaps, too. length should represent the final\n\t\t// defined item even if gaps were there previously. we don't want to\n\t\t// accidentally 'push' into a gap, which would put the item in the wrong place.\n\t\tconst isEndOfList = noGaps && i >= fromCopy.length;\n\n\t\t// this branch exclusively deals with object references.\n\t\tif (itemOid && oidsInFrom.has(itemOid)) {\n\t\t\t// this item was in the old list, so no matter what we want to\n\t\t\t// preserve its identity. the rest of the branches here all\n\t\t\t// assume the item is new and initialize it.\n\t\t\tif (areTheSameIdentity(value, oldValue)) {\n\t\t\t\t// the item hasn't moved. we just diff it in place.\n\t\t\t\tdiff(oldValue, value, ctx);\n\t\t\t} else {\n\t\t\t\t// the item has moved. we are currently visiting its new index,\n\t\t\t\t// so we can move it by reference now\n\t\t\t\tctx.patches.push(\n\t\t\t\t\t...ctx.patchCreator.createListMoveByRef(\n\t\t\t\t\t\toid,\n\t\t\t\t\t\tcreateRef(itemOid),\n\t\t\t\t\t\ti,\n\t\t\t\t\t\tctx.authz,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\t// the problem is, a move by ref is not the same as what\n\t\t\t\t// we really observed here, since it's more like an insertion\n\t\t\t\t// and not an overwrite. to complicate this, the replaced item\n\t\t\t\t// at this index might actually have moved, not been replaced.\n\t\t\t\t// we mark the item that was at this index previously, and if\n\t\t\t\t// we don't see it later, we'll delete it.\n\t\t\t\tconst fromOid = maybeGetOid(oldValue);\n\t\t\t\tif (fromOid) {\n\t\t\t\t\toverwrittenItems.add(fromOid);\n\t\t\t\t}\n\n\t\t\t\t// remember this item so we don't delete it later.\n\t\t\t\tmovedItems.add(itemOid);\n\t\t\t}\n\t\t} else if (isEndOfList) {\n\t\t\t// this will initialize all sub-objects in the item, too\n\t\t\tctx.patches.push(\n\t\t\t\t...ctx.patchCreator.createListPush(oid, value, ctx.authz),\n\t\t\t);\n\t\t} else if (areTheSameIdentity(value, oldValue)) {\n\t\t\t// note : since the branch above covers object references which\n\t\t\t// were present in the original list, logically this branch only\n\t\t\t// covers primitives. either way, call diff, it's just more\n\t\t\t// proper to do so.\n\t\t\tdiff(oldValue, value, ctx);\n\t\t} else {\n\t\t\t// the identity of this item has changed. we can now evaluate\n\t\t\t// whether we should replace the original item or insert a new\n\t\t\t// item.\n\n\t\t\t// we can insert an item if the items which used to be at this\n\t\t\t// index and the one before it are still in the list next to the\n\t\t\t// new item.\n\t\t\t// i.e. [0,1,2,3] -> [0,1,4,2,3] can insert 4 at index 2.\n\t\t\t// theoretically we could support inserting a group of items,\n\t\t\t// like [0,1,2,3] -> [0,1,4,5,6,2,3], but in practice this is much\n\t\t\t// harder to detect.\n\t\t\tconst isPreviousItemStillThere =\n\t\t\t\ti === 0 || areTheSameIdentity(to[i - 1], fromCopy[i - 1]);\n\t\t\tconst isNextItemStillThere =\n\t\t\t\ti === to.length - 1 ||\n\t\t\t\tareTheSameIdentity(\n\t\t\t\t\tto[i + 1],\n\t\t\t\t\t// only \"i\" here because in the prior list, this was the item\n\t\t\t\t\t// at the insertion point.\n\t\t\t\t\tfromCopy[i],\n\t\t\t\t);\n\t\t\tif (isPreviousItemStillThere && isNextItemStillThere) {\n\t\t\t\tctx.patches.push(\n\t\t\t\t\t...ctx.patchCreator.createListInsert(oid, i, value, ctx.authz),\n\t\t\t\t);\n\t\t\t\t// mutate from copy to mirror this insert so further comparisons\n\t\t\t\t// are correct. we just insert an undefined.\n\t\t\t\tfromCopy.splice(i, 0, undefined);\n\t\t\t} else {\n\t\t\t\t// if we can't insert, we have to replace the item.\n\t\t\t\tctx.patches.push(\n\t\t\t\t\t...ctx.patchCreator.createListSet(oid, i, value, ctx.authz),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t// remove any remaining items at the end of the array.\n\tconst deletedItemsAtEnd = fromCopy.length - to.length;\n\tif (deletedItemsAtEnd > 0) {\n\t\tfor (let i = fromCopy.length - 1; i >= to.length; i--) {\n\t\t\tconst value = fromCopy[i];\n\t\t\tconst itemOid = maybeGetOid(value);\n\t\t\tif (itemOid) {\n\t\t\t\t// avoid deleting moved objects that were at the end of the list before.\n\t\t\t\t// their reference was moved elsewhere, but their contents must be retained.\n\t\t\t\tif (!movedItems.has(itemOid)) {\n\t\t\t\t\t// if sub-items were objects, we need to delete them all\n\t\t\t\t\t// this should recursively delete children of these items\n\t\t\t\t\t// also!\n\t\t\t\t\tdeleteWithSubObjects(value, ctx);\n\t\t\t\t\tctx.patches.push(\n\t\t\t\t\t\t...ctx.patchCreator.createListRemove(\n\t\t\t\t\t\t\toid,\n\t\t\t\t\t\t\tcreateRef(itemOid),\n\t\t\t\t\t\t\t'last',\n\t\t\t\t\t\t\tctx.authz,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tctx.patches.push(\n\t\t\t\t\t...ctx.patchCreator.createListRemove(oid, value, 'last', ctx.authz),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const overwrittenOid of overwrittenItems) {\n\t\tif (movedItems.has(overwrittenOid)) {\n\t\t\t// this item was moved, not overwritten. we don't want to delete it.\n\t\t\tcontinue;\n\t\t}\n\t\t// this item was overwritten, not moved. we need to delete it.\n\t\t// if sub-items were objects, we need to delete them all\n\t\t// this should recursively delete children of these items\n\t\t// also!\n\t\tconst item = from.find((x) => maybeGetOid(x) === overwrittenOid);\n\t\tif (item) {\n\t\t\tdeleteWithSubObjects(item, ctx);\n\t\t}\n\t\tctx.patches.push(\n\t\t\t...ctx.patchCreator.createListRemove(\n\t\t\t\toid,\n\t\t\t\tcreateRef(overwrittenOid),\n\t\t\t\t'last',\n\t\t\t\tctx.authz,\n\t\t\t),\n\t\t);\n\t}\n}\n\nexport function diffObjects(from: any, to: any, ctx: DiffContext) {\n\tconst oldKeys = new Set(Object.keys(from));\n\tconst oid = getOid(from);\n\tfor (const key in to) {\n\t\tconst value = to[key];\n\t\tif (value === undefined && ctx.merge) continue;\n\t\toldKeys.delete(key);\n\t\tif (isOidKey(key)) continue; // legacy\n\t\tconst oldValue = from[key];\n\t\tif (!isDiffableObject(value)) {\n\t\t\tif (!areTheSameIdentity(value, oldValue)) {\n\t\t\t\t// the value has changed for this key\n\t\t\t\t// if the value is undefined (merge is off), delete instead of\n\t\t\t\t// set.\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\tctx.patches.push(\n\t\t\t\t\t\t...ctx.patchCreator.createRemove(oid, key, ctx.authz),\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tctx.patches.push(\n\t\t\t\t\t\t...ctx.patchCreator.createSet(oid, key, value, ctx.authz),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// if there was an old value at this key, delete it.\n\t\t\t\tdeleteWithSubObjects(oldValue, ctx);\n\t\t\t} else {\n\t\t\t\t// two primitive, non-diffable values of the\n\t\t\t\t// same identity are considered equal.\n\t\t\t\t// we have nothing to do here.\n\t\t\t}\n\t\t} else {\n\t\t\t// make sure incoming object has a valid OID assigned,\n\t\t\t// and/or copy the existing value's OID if mergeUnknownObjects is\n\t\t\t// true.\n\t\t\tenforceAssignedOid(oid, value, maybeGetOid(oldValue), ctx);\n\t\t\tif (!oldValue) {\n\t\t\t\t// set the new value on this key\n\t\t\t\tctx.patches.push(\n\t\t\t\t\t...ctx.patchCreator.createSet(oid, key, value, ctx.authz),\n\t\t\t\t);\n\t\t\t} else if (!areTheSameIdentity(value, oldValue)) {\n\t\t\t\t// overwrite the key with the changed value\n\t\t\t\tctx.patches.push(\n\t\t\t\t\t...ctx.patchCreator.createSet(oid, key, value, ctx.authz),\n\t\t\t\t);\n\t\t\t\t// and we must also fully delete the\n\t\t\t\t// old object and its children\n\t\t\t\tdeleteWithSubObjects(oldValue, ctx);\n\t\t\t} else {\n\t\t\t\t// finally, this is the case when the identity of\n\t\t\t\t// the new and old values are the same -- we still\n\t\t\t\t// have to diff the contents.\n\t\t\t\tdiff(oldValue, value, ctx);\n\t\t\t}\n\t\t}\n\t}\n\t// this set now only contains keys which were not in the new object\n\tif (!ctx.merge) {\n\t\tfor (const key of oldKeys) {\n\t\t\tif (isOidKey(key)) continue;\n\t\t\t// remove the key entirely\n\t\t\tctx.patches.push(...ctx.patchCreator.createRemove(oid, key, ctx.authz));\n\t\t\t// push the deletes for the contents of the item\n\t\t\tdeleteWithSubObjects(from[key], ctx);\n\t\t}\n\t}\n}\n\nexport function deleteWithSubObjects(root: any, ctx: DiffContext) {\n\tif (!isDiffableObject(root)) {\n\t\treturn;\n\t}\n\tconst oid = maybeGetOid(root);\n\tif (oid) {\n\t\tctx.patches.push(...ctx.patchCreator.createDelete(oid, ctx.authz));\n\t\tfor (const key in root) {\n\t\t\tconst value = root[key];\n\t\t\tdeleteWithSubObjects(value, ctx);\n\t\t}\n\t}\n}\n", "import { generateId } from './utils.js';\n\nexport class EventSubscriber<\n\tEvents extends { [key: string]: (...args: any[]) => void },\n> {\n\tprotected subscribers: Record<\n\t\tstring,\n\t\tRecord<string, (...args: any[]) => void>\n\t> = {} as any;\n\tprotected counts: Record<string, number> = {} as any;\n\tprivate _disabled = false;\n\tprotected disposed = false;\n\n\tconstructor(private _onAllUnsubscribed?: (event: keyof Events) => void) {}\n\n\tget disabled() {\n\t\treturn this._disabled;\n\t}\n\n\tsubscriberCount = (event: Extract<keyof Events, string>) => {\n\t\treturn this.counts[event] ?? 0;\n\t};\n\n\ttotalSubscriberCount = () => {\n\t\treturn Object.values(this.counts).reduce((acc, count) => acc + count, 0);\n\t};\n\n\tsubscribe = <K extends Extract<keyof Events, string>>(\n\t\tevent: K,\n\t\tcallback: Events[K],\n\t) => {\n\t\tconst key = generateId();\n\t\tlet subscribers = this.subscribers[event];\n\t\tif (!subscribers) {\n\t\t\tsubscribers = this.subscribers[event] = {};\n\t\t}\n\t\tsubscribers[key] = callback;\n\t\tthis.counts[event] = (this.counts[event] || 0) + 1;\n\t\treturn () => {\n\t\t\t// already removed\n\t\t\tif (!this.subscribers[event]) return;\n\n\t\t\tdelete this.subscribers[event][key];\n\t\t\tthis.counts[event]--;\n\t\t\tif (this.counts[event] === 0) {\n\t\t\t\tdelete this.subscribers[event];\n\t\t\t\tdelete this.counts[event];\n\t\t\t\tif (this._onAllUnsubscribed) {\n\t\t\t\t\tthis._onAllUnsubscribed(event);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t};\n\n\temit = <K extends Extract<keyof Events, string>>(\n\t\tevent: K,\n\t\t...args: Parameters<Events[K]>\n\t) => {\n\t\tif (this._disabled) return;\n\t\tif (this.subscribers[event]) {\n\t\t\tObject.values(this.subscribers[event]).forEach((c) => c(...args));\n\t\t}\n\t};\n\n\tdispose = () => {\n\t\tthis._disabled = true;\n\t\tthis.disposed = true;\n\t\tconst events = Object.keys(this.subscribers);\n\t\tthis.subscribers = {} as any;\n\t\tthis.counts = {} as any;\n\t\tevents.forEach((event) => {\n\t\t\tif (this._onAllUnsubscribed) {\n\t\t\t\tthis._onAllUnsubscribed(event);\n\t\t\t}\n\t\t});\n\t};\n\n\tdisable = () => {\n\t\tthis._disabled = true;\n\t};\n}\n\nexport type EventsOf<T extends EventSubscriber<any>> =\n\tT extends EventSubscriber<infer E> ? keyof E : never;\n", "import {\n\tStorageCollectionSchema,\n\tStorageSyntheticIndexSchema,\n\tCollectionCompoundIndex,\n\tStorageDirectSyntheticSchema,\n} from './index.js';\n\n// unlikely to be used unicode character\nexport const COMPOUND_INDEX_SEPARATOR = '\\uFFFFFE';\n// 1 lower than separator\nexport const COMPOUND_INDEX_LOWER_BOUND_SEPARATOR = '\\u0000';\n// 1 higher than separator\nexport const COMPOUND_INDEX_UPPER_BOUND_SEPARATOR = '\\uFFFFFF';\n\ntype IndexableFieldValue = string | number | boolean | any[];\nexport type CompoundIndexValue = string | string[];\n\nexport function createCompoundIndexValue(\n\t...fields: IndexableFieldValue[]\n): CompoundIndexValue {\n\tconst value = expandArrayIndex(fields);\n\tif (value.length === 1) {\n\t\treturn value[0];\n\t}\n\treturn value;\n}\n\nexport function createUpperBoundIndexValue(\n\t...fields: IndexableFieldValue[]\n): string {\n\treturn (\n\t\tfields.join(COMPOUND_INDEX_SEPARATOR) +\n\t\t`${COMPOUND_INDEX_UPPER_BOUND_SEPARATOR}`\n\t);\n}\n\nexport function createLowerBoundIndexValue(\n\t...fields: IndexableFieldValue[]\n): string {\n\treturn (\n\t\tfields.join(COMPOUND_INDEX_SEPARATOR) +\n\t\t`${COMPOUND_INDEX_SEPARATOR}${COMPOUND_INDEX_LOWER_BOUND_SEPARATOR}`\n\t);\n}\n\n/**\n * Whenever an array value is included in a compound index, we have to expand\n * the value to include all permutations of values in the array.\n * For example if we had an index id + tags on a document\n *\n * {\n * id: '1',\n * tags: ['a', 'b']\n * }\n *\n * we want to create an index:\n *\n * id_tags: ['1#a', '1#b']\n *\n * If multiple arrays are indexed we have to exponentially expand...\n *\n * id_tags_tags2: ['1#a#a', '1#a#b', '1#b#a', '1#b#b']\n *\n * To generalize this we construct a 2-level array of strings.\n * Iterating over indexed values, we expand each item into N items if\n * the current value is an array.\n *\n * Then we combine all nested arrays into compound index values.\n * This will produce an array of 1 element if none of the indexed values\n * were arrays. The caller should unwrap that.\n *\n * This function also deduplicates values.\n */\nfunction expandArrayIndex(fields: IndexableFieldValue[]): string[] {\n\tlet value: string[][] = [[]];\n\tfor (const field of fields) {\n\t\tif (Array.isArray(field)) {\n\t\t\tconst newValue: string[][] = [];\n\t\t\tfor (const previousValue of value) {\n\t\t\t\tfor (const fieldValue of field) {\n\t\t\t\t\tnewValue.push(previousValue.concat(fieldValue));\n\t\t\t\t}\n\t\t\t}\n\t\t\tvalue = newValue;\n\t\t} else {\n\t\t\tfor (const item of value) {\n\t\t\t\titem.push(`${field}`);\n\t\t\t}\n\t\t}\n\t}\n\treturn Array.from(\n\t\tnew Set(\n\t\t\tvalue.map((item) => {\n\t\t\t\treturn item.join(COMPOUND_INDEX_SEPARATOR);\n\t\t\t}),\n\t\t),\n\t);\n}\n\nexport function isDirectSynthetic(\n\tindex: any,\n): index is StorageDirectSyntheticSchema<any> {\n\treturn !!index.field;\n}\n\nexport function computeSynthetics(schema: StorageCollectionSchema, obj: any) {\n\tconst result: Record<string, any> = {};\n\tfor (const [name, property] of Object.entries(schema.indexes || {})) {\n\t\tconst index = property as StorageSyntheticIndexSchema<any>;\n\t\tif (isDirectSynthetic(index)) {\n\t\t\tresult[name] = sanitizeIndexValue(obj[index.field]);\n\t\t} else {\n\t\t\tresult[name] = sanitizeIndexValue(index.compute(obj));\n\t\t}\n\t}\n\treturn result;\n}\n\nexport function computeCompoundIndices(\n\tschema: StorageCollectionSchema<any, any, any>,\n\tdoc: any,\n): any {\n\treturn Object.entries(schema.compounds || {}).reduce<\n\t\tRecord<string, CompoundIndexValue>\n\t>((acc, [indexKey, index]) => {\n\t\tacc[indexKey] = createCompoundIndexValue(\n\t\t\t...(index as CollectionCompoundIndex<any, any>).of.map(\n\t\t\t\t(key) => doc[key] as string | number,\n\t\t\t),\n\t\t);\n\t\treturn acc;\n\t}, {} as Record<string, CompoundIndexValue>);\n}\n\nfunction computeIndexedFields(schema: StorageCollectionSchema, doc: any) {\n\treturn Object.entries(schema.fields).reduce<Record<string, any>>(\n\t\t(acc, [key, field]) => {\n\t\t\t// TODO: remove once I'm comfortable dropping 'indexed' support\n\t\t\tif ('indexed' in field) {\n\t\t\t\tacc[key] = sanitizeIndexValue(doc[key]);\n\t\t\t}\n\t\t\treturn acc;\n\t\t},\n\t\t{},\n\t);\n}\n\nexport function getIndexValues(\n\tschema: StorageCollectionSchema<any, any, any>,\n\tdoc: any,\n) {\n\tconst basicIndexes: any = {\n\t\t[schema.primaryKey]: doc[schema.primaryKey],\n\t\t...computeIndexedFields(schema, doc),\n\t\t...computeSynthetics(schema, doc),\n\t};\n\tObject.assign(\n\t\tbasicIndexes,\n\t\tcomputeCompoundIndices(schema, { ...doc, ...basicIndexes }),\n\t);\n\treturn basicIndexes;\n}\n\nexport function assignIndexValues(\n\tschema: StorageCollectionSchema<any, any, any>,\n\tdoc: any,\n) {\n\tObject.assign(doc, computeSynthetics(schema, doc));\n\tObject.assign(doc, computeCompoundIndices(schema, doc));\n\treturn doc;\n}\n\nexport const NULL_INDEX_VALUE = 'null';\n\nexport function sanitizeIndexValue(\n\tvalue: unknown,\n): string | number | (string | number)[] {\n\tif (value === null) {\n\t\treturn NULL_INDEX_VALUE;\n\t}\n\tif (typeof value === 'string' || typeof value === 'number') {\n\t\treturn value;\n\t}\n\tif (typeof value === 'boolean' || value === null) {\n\t\treturn `${value}`;\n\t}\n\tif (value === undefined) {\n\t\t// this shouldn't happen ,but for resiliency...\n\t\treturn 'undefined';\n\t}\n\tif (Array.isArray(value)) {\n\t\treturn value.map(sanitizeIndexValue) as any;\n\t}\n\tthrow new Error(`Unsupported index value: ${value}`);\n}\n", "/**\n * Memoizes the last invocation of a function with the same memo keys.\n * As long as key identity and set doesn't change, the last computed\n * value will be returned.\n */\nexport function memoByKeys<TRet, TKeys extends any[]>(\n\tfn: (...args: unknown[]) => TRet,\n\tgetKeys: () => TKeys,\n): (...args: unknown[]) => TRet {\n\tlet cachedKeys: TKeys | undefined;\n\tlet cachedResult: TRet | undefined;\n\treturn (...args: unknown[]) => {\n\t\tconst keys = getKeys();\n\t\tif (\n\t\t\tcachedKeys &&\n\t\t\tcachedKeys.length === keys.length &&\n\t\t\tcachedKeys.every((key, i) => key === keys[i])\n\t\t) {\n\t\t\treturn cachedResult!;\n\t\t}\n\t\tcachedKeys = [...keys] as TKeys;\n\t\tcachedResult = fn(...args);\n\t\treturn cachedResult;\n\t};\n}\n", "import {\n\taddFieldDefaults,\n\tassert,\n\tassignOid,\n\tAuthorizationKey,\n\tCollectionFilter,\n\tgetOid,\n\tisMultiValueIndex,\n\tisRequired,\n\tremoveExtraProperties,\n\tstableStringify,\n\tStorageCollectionSchema,\n\tStorageDocument,\n\tStorageDocumentInit,\n\tStorageSchema,\n\tvalidateEntity,\n} from './index.js';\n\n/**@deprecated */\nexport interface DroppedCollectionMigrationStrategy<\n\tOld extends StorageCollectionSchema<any, any, any>,\n> {\n\t(old: Old): void | Promise<void>;\n}\n/**@deprecated */\nexport interface PreservedCollectionMigrationStrategy<\n\tOld extends StorageCollectionSchema<any, any, any>,\n\tNew extends StorageCollectionSchema<any, any, any>,\n> {\n\t(\n\t\told: StorageDocument<Old>,\n\t): StorageDocument<New> | Promise<StorageDocument<New>>;\n}\n/** @deprecated */\ntype MigrationStrategy<\n\tOld extends StorageCollectionSchema<any, any, any>,\n\tNew extends StorageCollectionSchema<any, any, any>,\n> =\n\t| DroppedCollectionMigrationStrategy<Old>\n\t| PreservedCollectionMigrationStrategy<Old, New>;\n/** @deprecated */\nexport type MigrationsKeyedOnCollection<\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> =\n\t| PreservedCollectionMigrations<Old, New>\n\t| DroppedCollectionMigrations<Old, New>;\n\n/**@deprecated */\ntype NotInSchema<\n\tName extends string | number | symbol,\n\tSchema extends StorageSchema<any>,\n> = Name extends keyof Schema['collections'] ? never : Name;\n/** @deprecated */\ntype InSchema<\n\tName extends string | number | symbol,\n\tSchema extends StorageSchema<any>,\n> = Name extends keyof Schema['collections'] ? Name : never;\n/** @deprecated */\ntype DroppedCollections<\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> = {\n\t[Key in keyof Old['collections'] as NotInSchema<\n\t\tKey,\n\t\tNew\n\t>]: StorageCollectionSchema<any, any, any>;\n};\n/** @deprecated */\ntype PreservedCollections<\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> = {\n\t[Key in keyof Old['collections'] as InSchema<\n\t\tKey,\n\t\tNew\n\t>]: StorageCollectionSchema<any, any, any>;\n};\n/** @deprecated */\ntype DroppedCollectionMigrations<\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> = {\n\t[Key in keyof DroppedCollections<\n\t\tOld,\n\t\tNew\n\t>]: DroppedCollectionMigrationStrategy<Old['collections'][Key]>;\n};\n/** @deprecated */\ntype PreservedCollectionMigrations<\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> = {\n\t[Key in keyof PreservedCollections<\n\t\tOld,\n\t\tNew\n\t>]: PreservedCollectionMigrationStrategy<\n\t\tOld['collections'][Key],\n\t\tNew['collections'][Key]\n\t>;\n};\n\n/** @deprecated */\ntype StrategyFor<\n\tKey extends string,\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> = Key extends keyof New['collections']\n\t? PreservedCollectionMigrationStrategy<\n\t\t\tOld['collections'][Key],\n\t\t\tNew['collections'][Key]\n\t\t>\n\t: DroppedCollectionMigrationStrategy<Old['collections'][Key]>;\n\n/** @deprecated */\ntype DeprecatedMigrationRunner<\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> = <Collection extends Extract<keyof Old['collections'], string>>(\n\tcollection: Collection,\n\tstrategy: StrategyFor<Collection, Old, New>,\n) => Promise<void>;\n\n/** @deprecated */\ntype DeprecatedMigrationQueryMaker<\n\tCollection extends StorageCollectionSchema<any, any, any>,\n> = {\n\tget(primaryKey: string): Promise<StorageDocument<Collection> | undefined>;\n\tfindOne(\n\t\tquery: CollectionFilter,\n\t): Promise<StorageDocument<Collection> | undefined>;\n\tfindAll(query?: CollectionFilter): Promise<StorageDocument<Collection>[]>;\n};\n\n/** @deprecated */\ntype DeprecatedMigrationQueries<Old extends StorageSchema<any>> = {\n\t[Key in keyof Old['collections']]: DeprecatedMigrationQueryMaker<\n\t\tOld['collections'][Key]\n\t>;\n};\n\n/** @deprecated */\ntype DeprecatedMigrationMutations<New extends StorageSchema> = {\n\t[Key in keyof New['collections']]: {\n\t\tput(\n\t\t\tdocument: StorageDocumentInit<New['collections'][Key]>,\n\t\t): Promise<StorageDocument<New['collections'][Key]>>;\n\t\tdelete(primaryKey: string): Promise<void>;\n\t};\n};\n/** @deprecated */\nexport interface DeprecatedMigrationTools<\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> {\n\tmigrate: DeprecatedMigrationRunner<Old, New>;\n\tidentity: <T>(val: T) => T;\n\t/**\n\t * @deprecated - default field values are automatically\n\t * applied during migration, you don't need to use this.\n\t * Please remove it from your migrations - even old ones\n\t * (old migrations can be updated!)\n\t */\n\twithDefaults: (collectionName: string, value: any) => any;\n\tqueries: DeprecatedMigrationQueries<Old>;\n\tmutations: DeprecatedMigrationMutations<New>;\n\tinfo: {\n\t\tchangedCollections: keyof Old['collections'][];\n\t\taddedCollections: keyof New['collections'][];\n\t\tremovedCollections: keyof Old['collections'][];\n\t};\n}\n\nexport interface MigrationEngine {\n\tmigrate: (collection: string, strategy: (val: any) => any) => Promise<void>;\n\tqueries: MigrationQueries<any>;\n\tmutations: MigrationMutations<any>;\n\t/** OIDs of any new documents created during the migration */\n\tnewOids: string[];\n\t/** Promises that should be resolved before completing the migration */\n\tawaitables: Promise<any>[];\n\t/** Deletes all documents in a collection - used for removed collections */\n\tdeleteCollection: (collection: string) => Promise<void>;\n\tlog: (...messages: any[]) => void;\n\tclose: () => Promise<void>;\n}\n/** @deprecated */\ntype DeprecatedMigrationProcedure<\n\tOld extends StorageSchema,\n\tNew extends StorageSchema,\n> = (tools: DeprecatedMigrationTools<Old, New>) => Promise<void>;\n\ntype EmptySchema = {\n\tversion: 0;\n\tcollections: {};\n};\nconst emptySchema: EmptySchema = {\n\tversion: 0,\n\tcollections: {},\n};\n\n/** @deprecated - use createMigration */\nexport function migrate<Schema extends StorageSchema>(\n\tschema: Schema,\n\tprocedure: DeprecatedMigrationProcedure<EmptySchema, Schema>,\n): Migration<EmptySchema, Schema>;\n/** @deprecated = use createMigration */\nexport function migrate<Old extends StorageSchema, New extends StorageSchema>(\n\toldSchema: Old,\n\tnewSchema: New,\n\tprocedure: DeprecatedMigrationProcedure<Old, New>,\n): Migration<Old, New>;\nexport function migrate(\n\toldSchemaOrNewSchema: any,\n\tnewSchemaOrProcedure: any,\n\tprocedureIfTwoSchemas?: any,\n) {\n\tconst isProcedureSecondArgument = typeof newSchemaOrProcedure === 'function';\n\tconst oldSchema = isProcedureSecondArgument\n\t\t? emptySchema\n\t\t: oldSchemaOrNewSchema;\n\tconst newSchema = isProcedureSecondArgument\n\t\t? oldSchemaOrNewSchema\n\t\t: newSchemaOrProcedure;\n\tconst procedure = isProcedureSecondArgument\n\t\t? newSchemaOrProcedure\n\t\t: procedureIfTwoSchemas;\n\t// diff to determine changed collections\n\tconst changedCollections: string[] = Object.keys(\n\t\tnewSchema.collections,\n\t).filter(\n\t\t(key) =>\n\t\t\toldSchema.collections[key] &&\n\t\t\tstableStringify(oldSchema.collections[key]) !==\n\t\t\t\tstableStringify(newSchema.collections[key]),\n\t);\n\tconst removedCollections: string[] = Object.keys(\n\t\toldSchema.collections,\n\t).filter((key) => !newSchema.collections[key]);\n\tconst addedCollections = Object.keys(newSchema.collections).filter(\n\t\t(key) => !oldSchema.collections[key],\n\t);\n\t// collections which added one or more field defaults\n\tconst autoMigratedCollections = new Set<string>();\n\tfor (const collection of changedCollections) {\n\t\tconst oldFields = oldSchema.collections[collection].fields;\n\t\tconst newFields = newSchema.collections[collection].fields;\n\t\t// a new default was added - we can auto-migrate it\n\t\tif (\n\t\t\tObject.keys(newFields).some(\n\t\t\t\t(key) => !oldFields[key]?.default && newFields[key]?.default,\n\t\t\t)\n\t\t) {\n\t\t\tautoMigratedCollections.add(collection);\n\t\t}\n\t\t// a field was removed - we can auto-migrate it\n\t\tif (Object.keys(oldFields).some((key) => !newFields[key])) {\n\t\t\tautoMigratedCollections.add(collection);\n\t\t}\n\t}\n\n\tconst addedIndexes: Record<string, MigrationIndexDescription[]> = {};\n\tconst removedIndexes: Record<string, MigrationIndexDescription[]> = {};\n\tfor (const changed of [...changedCollections, ...addedCollections]) {\n\t\tconst oldIndexes = getIndexes(oldSchema.collections[changed]);\n\t\tconst newIndexes = getIndexes(newSchema.collections[changed]);\n\t\tconst added = newIndexes.filter(\n\t\t\t(index) => !oldIndexes.find((i) => i.name === index.name),\n\t\t);\n\t\tconst removed = oldIndexes.filter(\n\t\t\t(index) => !newIndexes.find((i) => i.name === index.name),\n\t\t);\n\t\tif (added.length > 0) {\n\t\t\taddedIndexes[changed] = added;\n\t\t\t// FIXME: don't o(n^2) this\n\t\t\tif (changedCollections.includes(changed)) {\n\t\t\t\tautoMigratedCollections.add(changed);\n\t\t\t}\n\t\t}\n\t\tif (removed.length > 0) {\n\t\t\tremovedIndexes[changed] = removed;\n\t\t\t// FIXME: don't o(n^2) this\n\t\t\tif (changedCollections.includes(changed)) {\n\t\t\t\tautoMigratedCollections.add(changed);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst withDefaults = (collectionName: string, val: any) => {\n\t\treturn addFieldDefaults(newSchema.collections[collectionName], val);\n\t};\n\tconst autoMigration = (collectionName: string) => (val: any) => {\n\t\tconst collection = newSchema.collections[collectionName];\n\t\treturn addFieldDefaults(collection, removeExtraProperties(collection, val));\n\t};\n\n\treturn {\n\t\tversion: newSchema.version,\n\t\tmigrate: async (engine: MigrationEngine) => {\n\t\t\tconst migratedCollections: string[] = [];\n\t\t\tawait procedure({\n\t\t\t\tmigrate: async (collection: any, strategy: any) => {\n\t\t\t\t\tconst auto = autoMigration(collection);\n\t\t\t\t\tconst wrapped = async (val: any) => {\n\t\t\t\t\t\tconst baseValue = await strategy(val);\n\t\t\t\t\t\t// assign OID from original value in case user's strategy\n\t\t\t\t\t\t// involves cloning\n\t\t\t\t\t\tassignOid(baseValue, getOid(val));\n\t\t\t\t\t\tconst result = auto(baseValue);\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t};\n\t\t\t\t\t// @ts-ignore\n\t\t\t\t\tawait engine.migrate(collection, wrapped);\n\t\t\t\t\tmigratedCollections.push(collection);\n\t\t\t\t\t// since the user migrated this one and we wrap their\n\t\t\t\t\t// strategy with auto-migration, we can remove it from\n\t\t\t\t\t// the auto-migration list\n\t\t\t\t\tautoMigratedCollections.delete(collection);\n\t\t\t\t},\n\t\t\t\tidentity: (val: any) => val,\n\t\t\t\twithDefaults,\n\t\t\t\tinfo: {\n\t\t\t\t\tchangedCollections,\n\t\t\t\t\taddedCollections,\n\t\t\t\t\tremovedCollections,\n\t\t\t\t},\n\t\t\t\tqueries: engine.queries,\n\t\t\t\tmutations: engine.mutations,\n\t\t\t});\n\n\t\t\t// mandatory migration of fields which had defaults added or\n\t\t\t// fields removed but weren't migrated by the user\n\n\t\t\tif (newSchema.version > 1) {\n\t\t\t\tengine.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'auto-migrating collections with new defaults',\n\t\t\t\t\tautoMigratedCollections,\n\t\t\t\t);\n\t\t\t\tfor (const name of autoMigratedCollections) {\n\t\t\t\t\tawait engine.migrate(name, autoMigration(name));\n\t\t\t\t\tmigratedCollections.push(name);\n\t\t\t\t}\n\n\t\t\t\tconst unmigrated = changedCollections.filter(\n\t\t\t\t\t(collection) => !migratedCollections.includes(collection),\n\t\t\t\t);\n\t\t\t\tif (unmigrated.length > 0) {\n\t\t\t\t\t// TODO: does this deserve a full-on error?\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`Unmigrated changed collections from version ${oldSchema.version} to version ${newSchema.version}:`,\n\t\t\t\t\t\tunmigrated,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tremovedCollections,\n\t\taddedIndexes,\n\t\tremovedIndexes,\n\t\tallCollections: Object.keys(newSchema.collections),\n\t\tchangedCollections,\n\t\taddedCollections,\n\t\toldCollections: Object.keys(oldSchema.collections),\n\t\toldSchema,\n\t\tnewSchema,\n\t};\n}\n\nexport interface MigrationIndexDescription {\n\tname: string;\n\t/**\n\t * The index writes multiple entries. Any value which matches\n\t * a lookup on this index should return the associated document.\n\t */\n\tmultiEntry: boolean;\n\t/**\n\t * Whether this index is a synthetic index. Synthetic indexes are\n\t * computed from other fields.\n\t */\n\tsynthetic: boolean;\n\t/**\n\t * Whether this index is a compound index. Compound indexes are\n\t * created from multiple fields in the collection merged into one\n\t * value.\n\t */\n\tcompound: boolean;\n\t/**\n\t * The base type of the values for this index. Multientry indexes\n\t * store multiple values of this type.\n\t */\n\ttype: 'string' | 'number' | 'boolean';\n}\n\nexport interface Migration<\n\tOld extends StorageSchema = any,\n\tNew extends StorageSchema = any,\n> {\n\tversion: number;\n\toldSchema: Old;\n\tnewSchema: New;\n\tmigrate: (engine: MigrationEngine) => Promise<void>;\n\t/** Collections which are added in the new schema and not present in the old */\n\taddedCollections: string[];\n\t/** Collections which were removed from the old schema */\n\tremovedCollections: string[];\n\t/** All collections which exist after the migration has completed - i.e. the ones in the new schema */\n\tallCollections: string[];\n\t/** Only the collections which were in the old schema */\n\toldCollections: string[];\n\t/** Collections whose fields or indexes changed between schemas */\n\tchangedCollections: string[];\n\t// new indexes mapped by collection name\n\taddedIndexes: Record<string, MigrationIndexDescription[]>;\n\t// removed indexes mapped by collection name\n\tremovedIndexes: Record<string, MigrationIndexDescription[]>;\n}\n\nexport function migrationRange(from: number, to: number) {\n\treturn [...Array(to - from).keys()].map((i) => 1 + i + from);\n}\n\nfunction getIndexes<Coll extends StorageCollectionSchema<any, any, any>>(\n\tcollection: Coll | undefined,\n): MigrationIndexDescription[] {\n\tif (!collection) return [];\n\n\treturn [\n\t\t...Object.keys(collection.indexes || {}).map((key) => {\n\t\t\t// lookup name-based indexes to get type from original\n\t\t\t// field.\n\t\t\tconst index = collection.indexes[key];\n\t\t\tlet indexType = index.type;\n\t\t\tif (!indexType && index.field) {\n\t\t\t\tindexType = collection.fields[index.field].type;\n\t\t\t}\n\t\t\tassert(\n\t\t\t\tindexType,\n\t\t\t\t`Could not determine type of index ${collection}.${key}. Index must have a type. Perhaps your schema is malformed?`,\n\t\t\t);\n\n\t\t\tconst multiEntry = isMultiValueIndex(collection, key);\n\n\t\t\treturn {\n\t\t\t\tname: key,\n\t\t\t\tmultiEntry,\n\t\t\t\tsynthetic: true,\n\t\t\t\tcompound: false,\n\t\t\t\ttype: indexType?.replace('[]', '') as any,\n\t\t\t};\n\t\t}),\n\t\t...Object.keys(collection.compounds || {}).map((key) => ({\n\t\t\tname: key,\n\t\t\tmultiEntry: isMultiValueIndex(collection, key),\n\t\t\tsynthetic: false,\n\t\t\tcompound: true,\n\t\t\ttype: 'string' as const,\n\t\t})),\n\t];\n}\n\n/** @deprecated - use createMigration with no procedure function */\nexport function createDefaultMigration(\n\tschema: StorageSchema,\n): Migration<{ version: 0; collections: {} }>;\n/** @deprecated - use createMigration with no procedure function */\nexport function createDefaultMigration<Old extends StorageSchema>(\n\toldSchema: Old,\n\tnewSchema: StorageSchema,\n): Migration<Old>;\nexport function createDefaultMigration(\n\tschema: StorageSchema,\n\tnewSchema?: StorageSchema<any>,\n) {\n\tlet oldSchema = newSchema\n\t\t? schema\n\t\t: {\n\t\t\t\tversion: 0,\n\t\t\t\tcollections: {},\n\t\t\t};\n\treturn migrate(oldSchema, newSchema || schema, async ({ migrate, info }) => {\n\t\tif ((newSchema || schema).version === 1) return;\n\n\t\tfor (const collection of info.changedCollections as any) {\n\t\t\t// @ts-ignore indefinite type resolution\n\t\t\tawait migrate(collection, (old) => old);\n\t\t}\n\t});\n}\n\n/** New, simpler type-safety migration tools */\ntype DocumentShape<Init = any, Snapshot = any> = {\n\tinit: Init;\n\tsnapshot: Snapshot;\n};\ntype SchemaDocuments = Record<string, DocumentShape>;\ntype CollectionProcedure<OldSnapshot, NewInit> = {\n\t(old: OldSnapshot): NewInit | Promise<NewInit>;\n};\ntype MigrationQueries<Old extends SchemaDocuments> = {\n\t[Key in keyof Old]: {\n\t\tget(primaryKey: string): Promise<Old[Key]['snapshot'] | undefined>;\n\t\tfindOne(query: CollectionFilter): Promise<Old[Key]['snapshot'] | undefined>;\n\t\tfindAll(query?: CollectionFilter): Promise<Old[Key]['snapshot'][]>;\n\t};\n};\ntype MigrationMutations<New extends SchemaDocuments> = {\n\t[Key in keyof New]: {\n\t\tput(\n\t\t\tdocument: New[Key]['init'],\n\t\t\toptions?: { access?: AuthorizationKey },\n\t\t): Promise<New[Key]['snapshot']>;\n\t\tdelete(primaryKey: string): Promise<void>;\n\t};\n};\ntype MigrationTools<\n\tOld extends SchemaDocuments,\n\tNew extends SchemaDocuments,\n> = {\n\t/**\n\t * Process a change in a collection's documents by taking in each existing\n\t * document and returning its new shape. This is typed so you can be\n\t * confident the proper transformations are made.\n\t */\n\tmigrate: <Collection extends keyof Old & keyof New>(\n\t\tcollection: Collection,\n\t\tstrategy: CollectionProcedure<\n\t\t\tOld[Collection]['snapshot'],\n\t\t\tNew[Collection]['init']\n\t\t>,\n\t) => Promise<void>;\n\tmutations: MigrationMutations<New>;\n\tqueries: MigrationQueries<Old>;\n\tinfo: {\n\t\tchangedCollections: (keyof Old & keyof New)[];\n\t\taddedCollections: (keyof New)[];\n\t\tremovedCollections: (keyof Old)[];\n\t};\n};\ntype MigrationProcedure<\n\tOld extends SchemaDocuments,\n\tNew extends SchemaDocuments,\n> = {\n\t(tools: MigrationTools<Old, New>): Promise<void>;\n};\ntype InitialMigrationTools<New extends SchemaDocuments> = {\n\tmutations: MigrationMutations<New>;\n};\ntype InitialMigrationProcedure<New extends SchemaDocuments> = {\n\t(tools: InitialMigrationTools<New>): Promise<void>;\n};\n\nexport function createMigration<New extends SchemaDocuments>(\n\tnewSchema: StorageSchema,\n\tprocedure?: InitialMigrationProcedure<New>,\n): any;\nexport function createMigration<\n\tOld extends SchemaDocuments,\n\tNew extends SchemaDocuments,\n>(\n\toldSchema: StorageSchema,\n\tnewSchema: StorageSchema,\n\tprocedure?: MigrationProcedure<Old, New>,\n): any;\nexport function createMigration(\n\tmaybeOldSchema: StorageSchema,\n\tmaybeNewSchemaOrProcedure?:\n\t\t| StorageSchema\n\t\t| InitialMigrationProcedure<SchemaDocuments>,\n\tmaybeProcedure?: MigrationProcedure<SchemaDocuments, SchemaDocuments>,\n): any {\n\tconst isProcedureSecondArgument =\n\t\ttypeof maybeNewSchemaOrProcedure === 'function' ||\n\t\tmaybeNewSchemaOrProcedure === undefined;\n\tconst oldSchema = isProcedureSecondArgument ? emptySchema : maybeOldSchema;\n\tconst newSchema = isProcedureSecondArgument\n\t\t? maybeOldSchema\n\t\t: maybeNewSchemaOrProcedure;\n\tconst procedure = isProcedureSecondArgument\n\t\t? maybeNewSchemaOrProcedure\n\t\t: maybeProcedure;\n\tassert(oldSchema, 'Invalid arguments to createMigration');\n\tassert(newSchema, 'Invalid arguments to createMigration');\n\tconst {\n\t\tchangedCollections,\n\t\taddedCollections,\n\t\tremovedCollections,\n\t\taddedIndexes,\n\t\tremovedIndexes,\n\t\tautoMigratedCollections,\n\t\tautoMigration,\n\t} = getMigrationInfo(oldSchema, newSchema);\n\n\treturn {\n\t\tversion: newSchema.version,\n\t\tmigrate: async (engine: MigrationEngine) => {\n\t\t\tconst migratedCollections: string[] = [];\n\t\t\tconst migrate = async (collection: any, strategy: any) => {\n\t\t\t\tconst auto = autoMigration(collection);\n\t\t\t\tconst wrapped = async (val: any) => {\n\t\t\t\t\tconst baseValue = await strategy(val);\n\t\t\t\t\t// assign OID from original value in case user's strategy\n\t\t\t\t\t// involves cloning\n\t\t\t\t\tassignOid(baseValue, getOid(val));\n\t\t\t\t\tconst result = auto(baseValue);\n\t\t\t\t\tconst validationError = validateEntity(\n\t\t\t\t\t\tnewSchema.collections[collection].fields,\n\t\t\t\t\t\tresult,\n\t\t\t\t\t);\n\t\t\t\t\tif (validationError) {\n\t\t\t\t\t\t// TODO: what? throw?\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t};\n\t\t\t\t// @ts-ignore\n\t\t\t\tawait engine.migrate(collection, wrapped);\n\t\t\t\tmigratedCollections.push(collection);\n\t\t\t\t// since the user migrated this one and we wrap their\n\t\t\t\t// strategy with auto-migration, we can remove it from\n\t\t\t\t// the auto-migration list\n\t\t\t\tautoMigratedCollections.delete(collection);\n\t\t\t};\n\t\t\tawait procedure?.({\n\t\t\t\tmigrate,\n\t\t\t\tinfo: {\n\t\t\t\t\tchangedCollections,\n\t\t\t\t\taddedCollections,\n\t\t\t\t\tremovedCollections,\n\t\t\t\t},\n\t\t\t\tqueries: engine.queries,\n\t\t\t\tmutations: engine.mutations,\n\t\t\t});\n\n\t\t\t// mandatory migration of fields which had defaults added or\n\t\t\t// fields removed but weren't migrated by the user\n\n\t\t\tif (newSchema.version > 1) {\n\t\t\t\tengine.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'auto-migrating collections with new defaults',\n\t\t\t\t\tautoMigratedCollections,\n\t\t\t\t);\n\t\t\t\tfor (const name of autoMigratedCollections) {\n\t\t\t\t\tawait engine.migrate(name, autoMigration(name));\n\t\t\t\t\tmigratedCollections.push(name);\n\t\t\t\t}\n\n\t\t\t\t// delete all documents in deleted collections\n\t\t\t\tfor (const name of removedCollections) {\n\t\t\t\t\tawait engine.deleteCollection(name);\n\t\t\t\t}\n\n\t\t\t\tconst unmigrated = changedCollections.filter(\n\t\t\t\t\t(collection) => !migratedCollections.includes(collection),\n\t\t\t\t);\n\t\t\t\tif (unmigrated.length > 0) {\n\t\t\t\t\t// TODO: does this deserve a full-on error?\n\t\t\t\t\tengine.log(\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t`Unmigrated changed collections from version ${oldSchema.version} to version ${newSchema.version}:`,\n\t\t\t\t\t\tunmigrated,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tremovedCollections,\n\t\taddedIndexes,\n\t\tremovedIndexes,\n\t\tallCollections: Object.keys(newSchema.collections),\n\t\tchangedCollections,\n\t\taddedCollections,\n\t\toldCollections: Object.keys(oldSchema.collections),\n\t\toldSchema,\n\t\tnewSchema,\n\t};\n}\n\n// common tools\nfunction getMigrationInfo(oldSchema: StorageSchema, newSchema: StorageSchema) {\n\tconst changedCollections: string[] = Object.keys(\n\t\tnewSchema.collections,\n\t).filter(\n\t\t(key) =>\n\t\t\toldSchema.collections[key] &&\n\t\t\tstableStringify(oldSchema.collections[key]) !==\n\t\t\t\tstableStringify(newSchema.collections[key]),\n\t);\n\tconst removedCollections: string[] = Object.keys(\n\t\toldSchema.collections,\n\t).filter((key) => !newSchema.collections[key]);\n\tconst addedCollections = Object.keys(newSchema.collections).filter(\n\t\t(key) => !oldSchema.collections[key],\n\t);\n\t// collections which added one or more field defaults\n\tconst autoMigratedCollections = new Set<string>();\n\tfor (const collection of changedCollections) {\n\t\tconst oldFields = oldSchema.collections[collection].fields;\n\t\tconst newFields = newSchema.collections[collection].fields;\n\t\t// a new default was added - we can auto-migrate it\n\t\tif (\n\t\t\tObject.keys(newFields).some(\n\t\t\t\t(key) =>\n\t\t\t\t\t(!oldFields[key] || isRequired(oldFields[key])) &&\n\t\t\t\t\t!isRequired(newFields[key]),\n\t\t\t)\n\t\t) {\n\t\t\tautoMigratedCollections.add(collection);\n\t\t}\n\t\t// a field was removed - we can auto-migrate it\n\t\tif (Object.keys(oldFields).some((key) => !newFields[key])) {\n\t\t\tautoMigratedCollections.add(collection);\n\t\t}\n\t}\n\n\tconst addedIndexes: Record<string, MigrationIndexDescription[]> = {};\n\tconst removedIndexes: Record<string, MigrationIndexDescription[]> = {};\n\tfor (const changed of [...changedCollections, ...addedCollections]) {\n\t\tconst oldIndexes = getIndexes(oldSchema.collections[changed]);\n\t\tconst newIndexes = getIndexes(newSchema.collections[changed]);\n\t\tconst added = newIndexes.filter(\n\t\t\t(index) => !oldIndexes.find((i) => i.name === index.name),\n\t\t);\n\t\tconst removed = oldIndexes.filter(\n\t\t\t(index) => !newIndexes.find((i) => i.name === index.name),\n\t\t);\n\t\tif (added.length > 0) {\n\t\t\taddedIndexes[changed] = added;\n\t\t\t// FIXME: don't o(n^2) this\n\t\t\tif (changedCollections.includes(changed)) {\n\t\t\t\tautoMigratedCollections.add(changed);\n\t\t\t}\n\t\t}\n\t\tif (removed.length > 0) {\n\t\t\tremovedIndexes[changed] = removed;\n\t\t\t// FIXME: don't o(n^2) this\n\t\t\tif (changedCollections.includes(changed)) {\n\t\t\t\tautoMigratedCollections.add(changed);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst withDefaults = (collectionName: string, val: any) => {\n\t\treturn addFieldDefaults(newSchema.collections[collectionName], val);\n\t};\n\tconst autoMigration = (collectionName: string) => (val: any) => {\n\t\tconst collection = newSchema.collections[collectionName];\n\t\treturn addFieldDefaults(collection, removeExtraProperties(collection, val));\n\t};\n\n\treturn {\n\t\tchangedCollections,\n\t\taddedCollections,\n\t\tremovedCollections,\n\t\taddedIndexes,\n\t\tremovedIndexes,\n\t\tautoMigratedCollections,\n\t\twithDefaults,\n\t\tautoMigration,\n\t};\n}\n", "export interface UserInfo<Profile, Presence> {\n\t/**\n\t * This is the ID representing the user who is utilizing a\n\t * replica client to connect to the storage network.\n\t * One user may have multiple replica clients active at once,\n\t * but their presence will only reflect the most recent\n\t * replica used.\n\t */\n\tid: string;\n\t/**\n\t * This is the ID representing the replica client that is\n\t * connected to the storage network. This is used to\n\t * identify the client when sending messages to it.\n\t */\n\treplicaId: string;\n\n\t/**\n\t * This is the user's server profile. This data is associated\n\t * with the logged in user of the app and cannot be modified\n\t * by the local replica directly.\n\t */\n\tprofile: Profile;\n\n\t/**\n\t * Presence info which can update frequently as a replica\n\t * makes changes. The shape of presence is up to you.\n\t */\n\tpresence: Presence;\n\n\t/**\n\t * This is the internal presence data that Verdant uses\n\t * for some built-in presence functionality. The client\n\t * should manage it transparently to the user.\n\t */\n\tinternal: VerdantInternalPresence;\n}\n\nexport type UserInfoUpdate<Profile = any, Presence = any> = Omit<\n\tUserInfo<Profile, Presence>,\n\t'internal' | 'profile'\n> & {\n\tinternal?: VerdantInternalPresence;\n};\n\nexport interface VerdantInternalPresence {\n\tviewId?: string;\n\tlastFieldId?: string;\n\tlastFieldTimestamp?: number;\n}\n\nexport const initialInternalPresence: VerdantInternalPresence = {};\n", "export interface ReplicaInfo {\n\tid: string;\n\tackedLogicalTime: string | null;\n}\n\n/**\n * Different token types allow different replica client behaviors.\n * - Realtime: allows the client to subscribe to realtime events.\n * - Push: allows the client to push and pull data with HTTP, but not use realtime.\n * - PassivePush: allows the client to push and pull data with HTTP, but offline changes\n * will be discarded on reconnect.\n * - PassiveRealtime: allows the client to subscribe to realtime events, but offline changes\n * \t\t will be discarded on reconnect.\n * - ReadOnlyPull: the client may only pull changes using HTTP. It may not subscribe\n * to realtime events or push changes.\n * - ReadOnlyRealtime: the client may only subscribe to realtime events or pull from HTTP.\n * It may not push changes.\n *\n * Choosing the right token type can optimize client storage metrics significantly when\n * many replicas are connecting to a library.\n */\nexport enum ReplicaType {\n\tRealtime,\n\tPush,\n\tPassiveRealtime,\n\tPassivePush,\n\tReadOnlyPull,\n\tReadOnlyRealtime,\n}\n", "import cuid from 'cuid';\nimport {\n\tShapeFromFieldsWithDefaults,\n\tShapeFromProperty,\n\tStorageAnyFieldSchema,\n\tStorageArrayFieldSchema,\n\tStorageBooleanFieldSchema,\n\tStorageFieldSchema,\n\tStorageFieldsSchema,\n\tStorageFileFieldSchema,\n\tStorageMapFieldSchema,\n\tStorageNumberFieldSchema,\n\tStorageObjectFieldSchema,\n\tStorageStringFieldSchema,\n} from './types.js';\n\ntype ObjectFieldArgs<Props extends StorageFieldsSchema> = {\n\t/** @deprecated - use fields. renamed for more consistency with collection root. */\n\tproperties?: Props;\n\tfields?: Props;\n\tnullable?: boolean;\n\tdefault?:\n\t\t| ShapeFromFieldsWithDefaults<Props>\n\t\t| (() => ShapeFromFieldsWithDefaults<Props>);\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n};\n\nfunction objectField<Props extends StorageFieldsSchema>(\n\targs: ObjectFieldArgs<Props>,\n): StorageObjectFieldSchema<Props> {\n\tconst { properties, fields, ...resolvedArgs } = args;\n\tconst props = properties || fields;\n\tif (!props) {\n\t\tthrow new Error('objectField must be passed a properties object');\n\t}\n\treturn {\n\t\ttype: 'object',\n\t\t...resolvedArgs,\n\t\tproperties: props,\n\t};\n}\n\n/**\n * Used for recursively defined field schemas. Replaces the original properties\n * of an object field with the provided fields. This will mutate the original field.\n */\nfunction replaceObjectFields(\n\tobject: StorageObjectFieldSchema<any>,\n\tfields: StorageFieldsSchema,\n): StorageObjectFieldSchema<any> {\n\tobject.properties = fields;\n\treturn object;\n}\n\ntype ArrayFieldArgs<T extends StorageFieldSchema> = {\n\titems: T;\n\tnullable?: boolean;\n\tdefault?: ShapeFromProperty<T>[] | (() => ShapeFromProperty<T>[]);\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n};\n\nfunction arrayField<T extends StorageFieldSchema>(\n\targs: ArrayFieldArgs<T>,\n): StorageArrayFieldSchema<T> {\n\treturn {\n\t\ttype: 'array',\n\t\t...args,\n\t};\n}\n\n/**\n * Used for recursively defined field schemas. Replaces the original items\n * of an array field with the provided items. This will mutate the original field.\n */\nfunction replaceArrayItems(\n\tarray: StorageArrayFieldSchema<any>,\n\titems: StorageFieldSchema,\n): StorageArrayFieldSchema<any> {\n\tarray.items = items;\n\treturn array;\n}\n\nconst stringField = (args?: {\n\tnullable?: boolean;\n\tdefault?: string | (() => string);\n\toptions?: string[];\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n}): StorageStringFieldSchema => {\n\treturn {\n\t\ttype: 'string',\n\t\t...args,\n\t};\n};\n\nconst numberField = (args?: {\n\tnullable?: boolean;\n\tdefault?: number | (() => number);\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n}): StorageNumberFieldSchema => {\n\treturn {\n\t\ttype: 'number',\n\t\t...args,\n\t};\n};\n\nconst booleanField = (args?: {\n\tnullable?: boolean;\n\tdefault?: boolean | (() => boolean);\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n}): StorageBooleanFieldSchema => {\n\treturn {\n\t\ttype: 'boolean',\n\t\t...args,\n\t};\n};\n\nconst anyField = <TShape>(args?: {\n\tdefault?: TShape;\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n}): StorageAnyFieldSchema<TShape> => {\n\treturn {\n\t\ttype: 'any',\n\t\t...args,\n\t};\n};\n\ntype MapFieldArgs<T extends StorageFieldSchema> = {\n\tvalues: T;\n\tdefault?:\n\t\t| Record<string, ShapeFromProperty<T>>\n\t\t| (() => Record<string, ShapeFromProperty<T>>);\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n};\nfunction mapField<T extends StorageFieldSchema>(\n\targs: MapFieldArgs<T>,\n): StorageMapFieldSchema<T> {\n\treturn {\n\t\ttype: 'map',\n\t\t...args,\n\t};\n}\n\n/**\n * Used for recursively defined field schemas. Replaces the original values\n * of a map field with the provided values. This will mutate the original field.\n */\nfunction replaceMapValues(\n\tmap: StorageMapFieldSchema<any>,\n\tvalues: StorageFieldSchema,\n): StorageMapFieldSchema<any> {\n\tmap.values = values;\n\treturn map;\n}\n\nconst fileField = (args?: {\n\tnullable?: boolean;\n\tdownloadRemote?: boolean;\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n}): StorageFileFieldSchema => {\n\treturn {\n\t\ttype: 'file',\n\t\t...args,\n\t};\n};\n\n/**\n * Meant for use on primary key fields. Do not use this to refer\n * to another document as a 'foreign key'\n */\nconst idField = (): StorageStringFieldSchema => {\n\treturn {\n\t\ttype: 'string',\n\t\tdefault: cuid,\n\t};\n};\n\nexport const fields = {\n\tobject: objectField,\n\tarray: arrayField,\n\treplaceObjectFields,\n\treplaceArrayItems,\n\tstring: stringField,\n\tnumber: numberField,\n\tboolean: booleanField,\n\tany: anyField,\n\tmap: mapField,\n\treplaceMapValues,\n\tfile: fileField,\n\tid: idField,\n};\n", "import {\n\tCollectionCompoundIndices,\n\tStorageCollectionSchema,\n\tStorageDirectSyntheticSchema,\n\tStorageFieldsSchema,\n\tStorageSchema,\n\tStorageSyntheticIndexSchema,\n\tStorageSyntheticIndices,\n} from './types.js';\nimport { fields } from './fieldHelpers.js';\nimport cuid from 'cuid';\n\nexport function collection<\n\tFields extends StorageFieldsSchema,\n\tSynthetics extends StorageSyntheticIndices<Fields>,\n\tCompounds extends CollectionCompoundIndices<Fields, Synthetics>,\n>({\n\tsynthetics,\n\tindexes,\n\t...input\n}: StorageCollectionSchema<\n\tFields,\n\tSynthetics,\n\tCompounds\n>): StorageCollectionSchema<Fields, Synthetics, Compounds> {\n\t// back compat - copy synthetics in with indexes\n\tconst finalIndexes = { ...synthetics, ...indexes };\n\t// add all indexed fields into the synthetic indices (back compat)\n\tfor (const [key, field] of Object.entries(input.fields)) {\n\t\tif ('indexed' in field) {\n\t\t\tfinalIndexes[key] = {\n\t\t\t\tfield: key,\n\t\t\t} as StorageDirectSyntheticSchema<Fields>;\n\t\t}\n\t}\n\treturn {\n\t\t...input,\n\t\tindexes: finalIndexes as Synthetics,\n\t};\n}\n\nexport function schema<\n\t// Fields extends StorageFieldsSchema,\n\t// Indexes extends StorageSyntheticIndices<Fields>,\n\t// Compounds extends CollectionCompoundIndices<Fields, Indexes>,\n\tSchema extends StorageSchema<{\n\t\t[key: string]: StorageCollectionSchema<any, any, any>;\n\t}>,\n>(input: Schema): StorageSchema {\n\treturn input;\n}\nschema.collection = collection;\nschema.fields = fields;\nschema.generated = {\n\tid: cuid,\n};\n\nexport * from './types.js';\n\nexport * from './indexFilters.js';\nexport * from './fields.js';\nexport * from './validation.js';\nexport * from './children.js';\n", "import {\n\tCollectionCompoundIndexFilter,\n\tCollectionFilter,\n\tMatchCollectionIndexFilter,\n\tRangeCollectionIndexFilter,\n\tSortIndexFilter,\n\tStartsWithIndexFilter,\n\tStorageCollectionSchema,\n} from './types.js';\n\nexport function isMatchIndexFilter(\n\tfilter: CollectionFilter,\n): filter is MatchCollectionIndexFilter {\n\treturn (filter as any).equals !== undefined;\n}\n\nexport function isRangeIndexFilter(\n\tfilter: CollectionFilter,\n): filter is RangeCollectionIndexFilter {\n\treturn (\n\t\t(filter as any).gte !== undefined ||\n\t\t(filter as any).lte !== undefined ||\n\t\t(filter as any).gt !== undefined ||\n\t\t(filter as any).lt !== undefined\n\t);\n}\n\nexport function isCompoundIndexFilter(\n\tfilter: CollectionFilter,\n): filter is CollectionCompoundIndexFilter {\n\treturn !!(filter as any).match;\n}\n\nexport function isStartsWithIndexFilter(\n\tfilter: CollectionFilter,\n): filter is StartsWithIndexFilter {\n\treturn (filter as any).startsWith !== undefined;\n}\n\nexport function isSortIndexFilter(\n\tfilter: CollectionFilter,\n): filter is SortIndexFilter {\n\treturn (\n\t\t!isRangeIndexFilter(filter) &&\n\t\t!isMatchIndexFilter(filter) &&\n\t\t!isCompoundIndexFilter(filter) &&\n\t\t!isStartsWithIndexFilter(filter) &&\n\t\t(filter as any).order\n\t);\n}\n\nexport function isMultiValueIndex(\n\tcollectionSchema: StorageCollectionSchema,\n\tindexName: string,\n): boolean {\n\tconst compound = collectionSchema.compounds?.[indexName];\n\tif (compound) {\n\t\treturn compound.of.some((fieldOrIndexName) => {\n\t\t\treturn isMultiValueIndex(collectionSchema, fieldOrIndexName);\n\t\t});\n\t}\n\tconst index = collectionSchema.indexes?.[indexName];\n\tif (index) {\n\t\tif ('type' in index) {\n\t\t\treturn isMultiEntryIndexType(index.type);\n\t\t}\n\t\tif ('field' in index) {\n\t\t\tconst field = collectionSchema.fields[index.field];\n\t\t\tif (!field) return false;\n\t\t\treturn isMultiEntryIndexType(field.type);\n\t\t}\n\t}\n\tconst field = collectionSchema.fields[indexName];\n\tif (!field) return false;\n\treturn isMultiEntryIndexType(field.type);\n}\n\nfunction isMultiEntryIndexType(type: string) {\n\treturn type === 'array' || type.endsWith('[]');\n}\n", "import { LEGACY_OID_KEY, OID_KEY } from '../oidsLegacy.js';\nimport { isObject } from '../utils.js';\nimport type {\n\tStorageCollectionSchema,\n\tStorageFieldSchema,\n\tStorageFieldsSchema,\n} from './types.js';\n\nexport function isNullable(field: StorageFieldSchema) {\n\tif (field.type === 'any') return true;\n\tif (field.type === 'map') return false;\n\treturn field.nullable;\n}\n\nexport function hasDefault(field: StorageFieldSchema | undefined) {\n\tif (!field) return false;\n\tif (field.type === 'map') return true;\n\tif (field.type === 'array') return true;\n\tif (field.type === 'file') return false;\n\treturn field.default !== undefined;\n}\n\nexport function isRequired(field: StorageFieldSchema) {\n\treturn !isNullable(field) && !hasDefault(field);\n}\n\nexport function isPrunePoint(field: StorageFieldSchema) {\n\treturn isNullable(field) || hasDefault(field);\n}\n\nexport function addFieldDefaults(\n\tcollection: StorageCollectionSchema,\n\tvalue: any,\n) {\n\tfor (const [key, field] of Object.entries(collection.fields)) {\n\t\tconst defaultValue = getFieldDefault(field);\n\t\tif (\n\t\t\t(defaultValue !== undefined && value[key] === undefined) ||\n\t\t\t// covers the case where a previously nullable field\n\t\t\t// now has a default during a new migration\n\t\t\t(!isNullable(field) && value[key] === null)\n\t\t) {\n\t\t\tvalue[key] = defaultValue;\n\t\t}\n\t\tif (value[key]) {\n\t\t\ttraverseCollectionFieldsAndApplyDefaults(value[key], field);\n\t\t}\n\t}\n\treturn value;\n}\n\nexport function traverseCollectionFieldsAndApplyDefaults(\n\tvalue: any,\n\tfield: StorageFieldSchema,\n) {\n\tif (value === undefined || value === null) return value;\n\tif (field.type === 'object') {\n\t\tfor (const [key, subField] of Object.entries(\n\t\t\tfield.properties as StorageFieldsSchema,\n\t\t)) {\n\t\t\tif (value[key] === undefined) {\n\t\t\t\tconst defaultValue = getFieldDefault(subField);\n\t\t\t\tif (defaultValue !== undefined) {\n\t\t\t\t\tvalue[key] = defaultValue;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttraverseCollectionFieldsAndApplyDefaults(value[key], subField);\n\t\t}\n\t} else if (field.type === 'array') {\n\t\tfor (const item of value) {\n\t\t\ttraverseCollectionFieldsAndApplyDefaults(item, field.items);\n\t\t}\n\t} else if (field.type === 'map') {\n\t\tfor (const [key, item] of Object.entries(value)) {\n\t\t\t// santiy check to weed out any id field\n\t\t\tif (key === OID_KEY || key === LEGACY_OID_KEY) continue;\n\t\t\ttraverseCollectionFieldsAndApplyDefaults(item, field.values);\n\t\t}\n\t}\n}\n\nexport function getFieldDefault(field: StorageFieldSchema): any {\n\tif ('default' in field) {\n\t\tconst val =\n\t\t\ttypeof field.default === 'function' ? field.default() : field.default;\n\t\tif (val === null) return val;\n\n\t\tconst cloned = structuredClone(val);\n\n\t\tif (field.type === 'object') {\n\t\t\t// objects also apply defaults of sub-fields over top of the default object\n\t\t\tfor (const [key, property] of Object.entries(\n\t\t\t\tfield.properties as StorageFieldsSchema,\n\t\t\t)) {\n\t\t\t\tif (cloned[key] === undefined) {\n\t\t\t\t\tcloned[key] = getFieldDefault(property);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn cloned;\n\t}\n\n\tif (isNullable(field)) {\n\t\treturn null;\n\t}\n\n\tif (field.type === 'array') {\n\t\treturn [];\n\t}\n\n\tif (field.type === 'map') {\n\t\treturn {};\n\t}\n\n\treturn undefined;\n}\n\nexport function removeExtraProperties(\n\tcollection: StorageCollectionSchema,\n\tvalue: any,\n) {\n\tfor (const [key, fieldValue] of Object.entries(value)) {\n\t\t// MUST NOT DELETE THESE!\n\t\tif (key === OID_KEY || key === LEGACY_OID_KEY) continue;\n\n\t\tif (!collection.fields[key]) {\n\t\t\tdelete value[key];\n\t\t} else {\n\t\t\ttraverseCollectionFieldsAndRemoveExtraProperties(\n\t\t\t\tfieldValue,\n\t\t\t\tcollection.fields[key],\n\t\t\t);\n\t\t}\n\t}\n\treturn value;\n}\n\nexport function traverseCollectionFieldsAndRemoveExtraProperties(\n\tvalue: any,\n\tfield: StorageFieldSchema,\n) {\n\tif (isObject(value) && field.type === 'object') {\n\t\tfor (const [key, fieldValue] of Object.entries(value)) {\n\t\t\tif (!field.properties[key]) {\n\t\t\t\tdelete value[key];\n\t\t\t} else {\n\t\t\t\ttraverseCollectionFieldsAndRemoveExtraProperties(\n\t\t\t\t\tfieldValue,\n\t\t\t\t\tfield.properties[key],\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t} else if (Array.isArray(value) && field.type === 'array') {\n\t\tfor (const item of value) {\n\t\t\ttraverseCollectionFieldsAndRemoveExtraProperties(item, field.items);\n\t\t}\n\t}\n}\n\nexport function isPrimitive(fieldSchema: StorageFieldSchema) {\n\treturn (\n\t\tfieldSchema.type === 'string' ||\n\t\tfieldSchema.type === 'number' ||\n\t\tfieldSchema.type === 'boolean'\n\t);\n}\n", "import { isFile, isFileData, isFileRef } from '../files.js';\nimport { OID_KEY } from '../oidsLegacy.js';\nimport { isObjectRef } from '../operation.js';\nimport { isObject } from '../utils.js';\nimport { hasDefault, isNullable } from './fields.js';\nimport { StorageFieldSchema, StorageFieldsSchema } from './types.js';\n\nexport function validateEntity(\n\tschema: StorageFieldsSchema,\n\tentity: any,\n): EntityValidationProblem | void {\n\tfor (const [key, value] of Object.entries(entity)) {\n\t\t// legacy -- old objects sometimes accidentally include this key\n\t\tif (key === OID_KEY) continue;\n\t\tif (!schema[key]) {\n\t\t\treturn {\n\t\t\t\ttype: 'invalid-key',\n\t\t\t\tfieldPath: [key],\n\t\t\t\tmessage: `Invalid field \"${key}\"`,\n\t\t\t};\n\t\t}\n\t\tif (value) {\n\t\t\tconst err = validateEntityField({\n\t\t\t\tfield: schema[key],\n\t\t\t\tvalue,\n\t\t\t\tfieldPath: [key],\n\t\t\t});\n\t\t\tif (err) return err;\n\t\t}\n\t}\n\treturn;\n}\n\nexport type EntityValidationProblem = {\n\ttype:\n\t\t| 'null'\n\t\t| 'no-default'\n\t\t| 'invalid-type'\n\t\t| 'invalid-value'\n\t\t| 'invalid-key';\n\tfieldPath: (string | number)[];\n\tmessage: string;\n};\n\nexport function validateEntityField({\n\tfield,\n\tvalue,\n\tfieldPath = [],\n\tdepth,\n\trequireDefaults,\n\texpectRefs,\n\thasPassedFirstLevel,\n}: {\n\tfield: StorageFieldSchema;\n\tvalue: any;\n\tfieldPath: (string | number)[];\n\tdepth?: number;\n\trequireDefaults?: boolean;\n\t/**\n\t * Run validation expecting refs, not nested objects. For validating\n\t * views (as opposed to inits/snapshots). Recommended to use depth 2\n\t * or no depth specified.\n\t */\n\texpectRefs?: boolean;\n\thasPassedFirstLevel?: boolean;\n}): EntityValidationProblem | undefined {\n\t// we only _actually_ start expecting refs after the first validation level.\n\t// TODO: something more... elegant?\n\tconst actuallyExpectRefs = expectRefs && hasPassedFirstLevel;\n\tif (depth !== undefined && depth <= 0) return;\n\n\tif (isNullable(field) && (value === null || value === undefined)) return;\n\tif (value === null || value === undefined) {\n\t\tif (requireDefaults || !hasDefault(field)) {\n\t\t\treturn {\n\t\t\t\ttype: 'no-default',\n\t\t\t\tfieldPath,\n\t\t\t\tmessage: `Invalid null value for field ${formatField(fieldPath)}`,\n\t\t\t};\n\t\t}\n\t}\n\n\tif (field.type === 'object') {\n\t\tif (actuallyExpectRefs) {\n\t\t\tif (!isObjectRef(value)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-type',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected ref for field ${formatField(\n\t\t\t\t\t\tfieldPath,\n\t\t\t\t\t)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t} else {\n\t\t\tif (!isObject(value)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-type',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected object ${\n\t\t\t\t\t\tfield.nullable ? 'or null ' : ''\n\t\t\t\t\t}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t\tfor (const [key, subField] of Object.entries(\n\t\t\t\tfield.properties as StorageFieldsSchema,\n\t\t\t)) {\n\t\t\t\t// legacy -- old objects sometimes accidentally include this key\n\t\t\t\tif (key === OID_KEY) continue;\n\t\t\t\tconst error = validateEntityField({\n\t\t\t\t\tfield: subField,\n\t\t\t\t\tvalue: value[key],\n\t\t\t\t\tfieldPath: [...fieldPath, key],\n\t\t\t\t\tdepth: depth !== undefined ? depth - 1 : undefined,\n\t\t\t\t\texpectRefs,\n\t\t\t\t\thasPassedFirstLevel: true,\n\t\t\t\t});\n\t\t\t\tif (error) {\n\t\t\t\t\treturn error;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// check for unexpected keys\n\t\t\tfor (const key of Object.keys(value)) {\n\t\t\t\tif (!field.properties[key]) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'invalid-key',\n\t\t\t\t\t\tfieldPath: [...fieldPath, key],\n\t\t\t\t\t\tmessage: `Invalid unexpected field \"${key}\" on value ${formatField(\n\t\t\t\t\t\t\tfieldPath,\n\t\t\t\t\t\t)}`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if (field.type === 'array') {\n\t\tif (actuallyExpectRefs) {\n\t\t\tif (!isObjectRef(value)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-type',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected ref for field ${formatField(\n\t\t\t\t\t\tfieldPath,\n\t\t\t\t\t)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t} else {\n\t\t\tif (!Array.isArray(value)) {\n\t\t\t\tif (value === null && field.nullable) return;\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-value',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected array ${\n\t\t\t\t\t\tfield.nullable ? 'or null ' : ''\n\t\t\t\t\t}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t\tfor (const item of value) {\n\t\t\t\tconst error = validateEntityField({\n\t\t\t\t\tfield: field.items,\n\t\t\t\t\tvalue: item,\n\t\t\t\t\tfieldPath: [...fieldPath, '[]'],\n\t\t\t\t\tdepth: depth !== undefined ? depth - 1 : undefined,\n\t\t\t\t\texpectRefs,\n\t\t\t\t\thasPassedFirstLevel: true,\n\t\t\t\t});\n\t\t\t\tif (error) {\n\t\t\t\t\treturn error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if (field.type === 'map') {\n\t\tif (actuallyExpectRefs) {\n\t\t\tif (!isObjectRef(value)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-type',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected ref for field ${formatField(\n\t\t\t\t\t\tfieldPath,\n\t\t\t\t\t)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t} else {\n\t\t\tif (!isObject(value)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-type',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected map for field ${formatField(\n\t\t\t\t\t\tfieldPath,\n\t\t\t\t\t)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t\tfor (const [key, item] of Object.entries(value)) {\n\t\t\t\tconst error = validateEntityField({\n\t\t\t\t\tfield: field.values,\n\t\t\t\t\tvalue: item,\n\t\t\t\t\tfieldPath: [...fieldPath, key],\n\t\t\t\t\tdepth: depth !== undefined ? depth - 1 : undefined,\n\t\t\t\t\texpectRefs,\n\t\t\t\t\thasPassedFirstLevel: true,\n\t\t\t\t});\n\t\t\t\tif (error) {\n\t\t\t\t\treturn error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if (field.type === 'string') {\n\t\tif (typeof value !== 'string') {\n\t\t\treturn {\n\t\t\t\ttype: 'invalid-type',\n\t\t\t\tfieldPath,\n\t\t\t\tmessage: `Expected string ${\n\t\t\t\t\tfield.nullable ? 'or null ' : ''\n\t\t\t\t}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,\n\t\t\t};\n\t\t}\n\t\tif (field.options && !field.options.includes(value)) {\n\t\t\treturn {\n\t\t\t\ttype: 'invalid-value',\n\t\t\t\tfieldPath,\n\t\t\t\tmessage: `Expected one of ${field.options.join(\n\t\t\t\t\t', ',\n\t\t\t\t)} for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,\n\t\t\t};\n\t\t}\n\t} else if (field.type === 'boolean') {\n\t\tif (typeof value !== 'boolean') {\n\t\t\treturn {\n\t\t\t\ttype: 'invalid-type',\n\t\t\t\tfieldPath,\n\t\t\t\tmessage: `Expected boolean ${\n\t\t\t\t\tfield.nullable ? 'or null ' : ''\n\t\t\t\t}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,\n\t\t\t};\n\t\t}\n\t} else if (field.type === 'number') {\n\t\tif (typeof value !== 'number') {\n\t\t\treturn {\n\t\t\t\ttype: 'invalid-type',\n\t\t\t\tfieldPath,\n\t\t\t\tmessage: `Expected number ${\n\t\t\t\t\tfield.nullable ? 'or null ' : ''\n\t\t\t\t}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,\n\t\t\t};\n\t\t}\n\t} else if (field.type === 'file') {\n\t\tif (actuallyExpectRefs) {\n\t\t\tif (!isFileRef(value)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-type',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected file ref for field ${formatField(\n\t\t\t\t\t\tfieldPath,\n\t\t\t\t\t)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t} else {\n\t\t\tif (!isFile(value) && !isFileData(value)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-type',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected file ${\n\t\t\t\t\t\tfield.nullable ? 'or null ' : ''\n\t\t\t\t\t}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction safeStringify(value: any) {\n\ttry {\n\t\treturn JSON.stringify(value);\n\t} catch (err) {\n\t\t// for example, recursive objects can't be stringified\n\t\treturn String(value);\n\t}\n}\n\nfunction formatField(fieldPath: (string | number)[]) {\n\tif (fieldPath.length === 0) return 'root';\n\treturn fieldPath.join('.');\n}\n\nexport function constrainEntity(schema: StorageFieldsSchema, entity: any): any {\n\tconst constrained: any = {};\n\tfor (const [key, value] of Object.entries(entity)) {\n\t\tif (!schema[key]) continue;\n\t\tconstrained[key] = constrainEntityField({\n\t\t\tfield: schema[key],\n\t\t\tvalue,\n\t\t\tfieldPath: [key],\n\t\t});\n\t}\n\treturn constrained;\n}\n\nexport function constrainEntityField({\n\tfield,\n\tvalue,\n\tfieldPath = [],\n\tdepth,\n}: {\n\tfield: StorageFieldSchema;\n\tvalue: any;\n\tfieldPath?: (string | number)[];\n\tdepth?: number;\n}): any {\n\tconst validationProblem = validateEntityField({\n\t\tfield,\n\t\tvalue,\n\t\tfieldPath,\n\t\tdepth,\n\t\trequireDefaults: true,\n\t});\n\n\tif (validationProblem) {\n\t\tthrow new Error(`Validation error: ${validationProblem.message}`);\n\t}\n\n\tif (field.type === 'object') {\n\t\tif (!isObject(value)) return value;\n\t\tconst constrained: any = {};\n\t\tfor (const [key, subField] of Object.entries(\n\t\t\tfield.properties as StorageFieldsSchema,\n\t\t)) {\n\t\t\tconstrained[key] = constrainEntityField({\n\t\t\t\tfield: subField,\n\t\t\t\tvalue: value[key],\n\t\t\t\tfieldPath: [...fieldPath, key],\n\t\t\t\tdepth: depth !== undefined ? depth - 1 : undefined,\n\t\t\t});\n\t\t}\n\t\treturn constrained;\n\t} else if (field.type === 'array') {\n\t\tif (!Array.isArray(value)) return value;\n\t\treturn value.map((item) =>\n\t\t\tconstrainEntityField({\n\t\t\t\tfield: field.items,\n\t\t\t\tvalue: item,\n\t\t\t\tfieldPath: [...fieldPath, '[]'],\n\t\t\t\tdepth: depth !== undefined ? depth - 1 : undefined,\n\t\t\t}),\n\t\t);\n\t} else if (field.type === 'map') {\n\t\tif (!isObject(value)) return value;\n\t\tconst constrained: any = {};\n\t\tfor (const [key, item] of Object.entries(value)) {\n\t\t\tconstrained[key] = constrainEntityField({\n\t\t\t\tfield: field.values,\n\t\t\t\tvalue: item,\n\t\t\t\tfieldPath: [...fieldPath, key],\n\t\t\t\tdepth: depth !== undefined ? depth - 1 : undefined,\n\t\t\t});\n\t\t}\n\t\treturn constrained;\n\t} else {\n\t\treturn value;\n\t}\n}\n", "import { StorageFieldSchema, StorageFieldsSchema } from './types.js';\n\nexport function getChildFieldSchema(\n\tschema: StorageFieldSchema | StorageFieldsSchema,\n\tkey: string | number,\n): StorageFieldSchema | null {\n\tif (schema.type === 'object') {\n\t\treturn schema.properties[key];\n\t} else if (schema.type === 'array') {\n\t\treturn schema.items;\n\t} else if (schema.type === 'map') {\n\t\treturn schema.values;\n\t} else if (schema.type === 'any') {\n\t\treturn schema;\n\t} else if (!('type' in schema)) {\n\t\treturn schema[key] ?? null;\n\t}\n\treturn null;\n}\n", "import cuid from 'cuid';\n\nexport interface TimestampProvider {\n\tnow(version: number): string;\n\tupdate(remoteTimestamp: string): void;\n\tzero(version: number): string;\n\tgetWallClockTime(timestamp: string): number;\n}\n\nconst VERSION_BLOCK_LENGTH = 4;\nconst ENCODING_NUMBER_RADIX = 36;\n\nexport function encodeVersion(version: number | string): string {\n\treturn version\n\t\t.toString(ENCODING_NUMBER_RADIX)\n\t\t.padStart(VERSION_BLOCK_LENGTH, '0');\n}\n\nexport function OLD_encodeVersion(version: number | string): string {\n\treturn version.toString().padStart(6, '0');\n}\n\nexport class NaiveTimestampProvider implements TimestampProvider {\n\tcounter = 0;\n\tnow = (version: number | string) => {\n\t\treturn (\n\t\t\tencodeVersion(version) + Date.now().toString() + '-' + this.counter++\n\t\t);\n\t};\n\tupdate = () => {\n\t\tthis.counter = 0;\n\t};\n\tzero = (version: number | string) => {\n\t\treturn encodeVersion(version) + '0' + '-' + this.counter++;\n\t};\n\tgetWallClockTime = (timestamp: string) => {\n\t\treturn parseInt(timestamp.slice(VERSION_BLOCK_LENGTH).split('-')[0], 10);\n\t};\n\n\treset() {\n\t\tthis.counter = 0;\n\t}\n}\n\n// good for tests that require determinism.\nexport class FixedTimestampProvider implements TimestampProvider {\n\ttime = new Date(2025, 2, 19).getTime().toString();\n\tcounter = 0;\n\tnow = (version: number | string) => {\n\t\treturn encodeVersion(version) + this.time + '-' + this.counter++;\n\t};\n\tupdate = () => {};\n\tzero = (version: number | string) => {\n\t\treturn encodeVersion(version) + '0' + '-' + this.counter++;\n\t};\n\tgetWallClockTime = () => 0;\n}\n\nexport class HybridLogicalClockTimestampProvider implements TimestampProvider {\n\tprivate latest: HLCTimestamp = {\n\t\ttime: Date.now(),\n\t\tcounter: 0,\n\t\tnode: generateNodeId(),\n\t};\n\tprivate zeroCounter = 0;\n\n\tnow = (version: string | number) => {\n\t\tthis.latest = getHlcNow(this.latest);\n\t\treturn this.get(version, this.latest);\n\t};\n\t/**\n\t * @deprecated - use now() instead and update to latest format\n\t */\n\tOLD_now = (version: string | number) => {\n\t\tthis.latest = getHlcNow(this.latest);\n\t\treturn OLD_encodeVersion(version) + OLD_serializeHlcTimestamp(this.latest);\n\t};\n\t/** Get the current timer state. Does not increment counter. */\n\ttimerState = () => {\n\t\treturn this.latest;\n\t};\n\tupdate = (remoteTimestamp: string) => {\n\t\t// strip version from remote timestamp\n\t\tconst hlcString = remoteTimestamp.slice(VERSION_BLOCK_LENGTH);\n\t\tthis.latest = updateFromRemote(\n\t\t\tthis.latest,\n\t\t\tdeserializeHlcTimestamp(hlcString),\n\t\t);\n\t};\n\tget = (version: string | number, raw: HLCTimestamp) => {\n\t\treturn encodeVersion(version) + serializeHlcTimestamp(raw);\n\t};\n\tzero = (version: string | number) => {\n\t\treturn (\n\t\t\tencodeVersion(version) +\n\t\t\tserializeHlcTimestamp({\n\t\t\t\ttime: 0,\n\t\t\t\t// to keep zero timestamps unique, we use a counter here as well\n\t\t\t\tcounter: this.zeroCounter++,\n\t\t\t\tnode: this.latest.node,\n\t\t\t})\n\t\t);\n\t};\n\tgetWallClockTime = getWallClockTime;\n}\n\nclass ClockDriftError extends Error {\n\ttype: string;\n\tconstructor(...args: any[]) {\n\t\tsuper();\n\t\tthis.type = 'ClockDriftError';\n\t\tthis.message = ['maximum clock drift exceeded'].concat(args).join(' ');\n\t}\n}\n\nclass OverflowError extends Error {\n\ttype: string;\n\tconstructor() {\n\t\tsuper();\n\t\tthis.type = 'OverflowError';\n\t\tthis.message = 'timestamp counter overflow';\n\t}\n}\n\ninterface HLCTimestamp {\n\ttime: number;\n\tcounter: number;\n\tnode: string;\n}\n\nconst COUNTER_BLOCK_LENGTH = 4;\nconst NODE_BLOCK_LENGTH = 7;\nconst MAX_CLOCK_DRIFT = 60 * 1000;\n// 9 base36 characters should last until the year 5000\n// when encoding a unix MS timestamp\nconst TIME_BLOCK_LENGTH = 9;\n\nfunction generateNodeId() {\n\treturn cuid\n\t\t.slug()\n\t\t.padStart(NODE_BLOCK_LENGTH, '0')\n\t\t.slice(0, NODE_BLOCK_LENGTH);\n}\n\nexport function serializeHlcTimestamp(ts: HLCTimestamp): string {\n\t// string representation of the time\n\tconst dateString = new Date(ts.time)\n\t\t.getTime()\n\t\t.toString(ENCODING_NUMBER_RADIX)\n\t\t.padStart(TIME_BLOCK_LENGTH, '0');\n\t// counter, 336, padded to 4 characters\n\tconst counter = ts.counter\n\t\t.toString(ENCODING_NUMBER_RADIX)\n\t\t.padStart(COUNTER_BLOCK_LENGTH, '0');\n\t// node id padded to 16 characters\n\tconst node = ts.node.padStart(NODE_BLOCK_LENGTH, '0');\n\treturn `${dateString}${counter}${node}`;\n}\n\nfunction getHlcNow(prev: HLCTimestamp): HLCTimestamp {\n\tconst wallTime = Date.now();\n\n\t// pick prev's time if it's later than our local device\n\tconst newWallTime = Math.max(prev.time, wallTime);\n\t// reset counter if wall time changed\n\tconst newCounter = prev.time === newWallTime ? prev.counter + 1 : 0;\n\n\t// check for drift\n\tif (newWallTime - wallTime > MAX_CLOCK_DRIFT) {\n\t\tthrow new ClockDriftError(newWallTime, wallTime, MAX_CLOCK_DRIFT);\n\t}\n\t// check for counter overflow (max is 4 bytes)\n\tif (newCounter > 65535) {\n\t\tthrow new OverflowError();\n\t}\n\n\treturn {\n\t\ttime: newWallTime,\n\t\tcounter: newCounter,\n\t\tnode: prev.node,\n\t};\n}\n\nfunction updateFromRemote(\n\tlocal: HLCTimestamp,\n\tremote: HLCTimestamp,\n): HLCTimestamp {\n\tconst wallTime = Date.now();\n\t// pick remote's time if it's later than our local device\n\tconst newTime = Math.max(wallTime, Math.max(local.time, remote.time));\n\n\tconst maxCounter = Math.max(local.counter, remote.counter);\n\tlet newCounter;\n\t// if all clocks are the same, increment the counter\n\tif (local.time === newTime && remote.time === newTime) {\n\t\tnewCounter = maxCounter + 1;\n\t}\n\t// if local time is the same as new time, increment our local counter\n\telse if (local.time === newTime) {\n\t\tnewCounter = local.counter + 1;\n\t}\n\t// if remote time is the same as new time, increment remote counter\n\telse if (remote.time === newTime) {\n\t\tnewCounter = remote.counter + 1;\n\t}\n\t// otherwise, reset the counter\n\telse {\n\t\tnewCounter = 0;\n\t}\n\n\t// check for drift\n\tif (newTime - wallTime > MAX_CLOCK_DRIFT) {\n\t\tthrow new ClockDriftError(newTime, wallTime, MAX_CLOCK_DRIFT);\n\t}\n\tif (newCounter > 65535) {\n\t\tthrow new OverflowError();\n\t}\n\n\treturn {\n\t\ttime: newTime,\n\t\tcounter: newCounter,\n\t\tnode: local.node,\n\t};\n}\n\nexport function deserializeHlcTimestamp(clock: string): HLCTimestamp {\n\tconst dateString = clock.slice(0, TIME_BLOCK_LENGTH);\n\tconst counter = clock.slice(\n\t\tTIME_BLOCK_LENGTH,\n\t\tTIME_BLOCK_LENGTH + COUNTER_BLOCK_LENGTH,\n\t);\n\tconst node = clock.slice(TIME_BLOCK_LENGTH + COUNTER_BLOCK_LENGTH);\n\tconst time = parseInt(dateString, ENCODING_NUMBER_RADIX);\n\tconst counterNum = parseInt(counter, ENCODING_NUMBER_RADIX);\n\n\tif (isNaN(time) || isNaN(counterNum)) {\n\t\tthrow new Error('invalid clock format');\n\t}\n\n\treturn {\n\t\ttime,\n\t\tcounter: counterNum,\n\t\tnode,\n\t};\n}\n\nfunction removeLeadingZeroes(str: string): string {\n\treturn str.replace(/^0+/, '');\n}\n\n/**\n * Below, converters for old-style timestamps are defined.\n * These are for migrating older clients to the new format.\n */\n\n/**\n * Converts a timestamp from the old format to the new format.\n */\nexport function convertOldHlcTimestamp(ts: string): string {\n\tconst versionBlock = ts.slice(0, 6);\n\t// no jokes please\n\tconst clockBlock = ts.slice(6);\n\tconst deserialized = OLD_deserializeHlcTimestamp(clockBlock);\n\n\t// version was base 10 and now is base 36\n\tconst versionNumber = parseInt(versionBlock, 10);\n\tconst encodedVersion = encodeVersion(versionNumber);\n\treturn encodedVersion + serializeHlcTimestamp(deserialized);\n}\n\nexport function OLD_serializeHlcTimestamp(ts: HLCTimestamp): string {\n\t// ISO string representation of the time\n\tconst dateString = new Date(ts.time).toISOString();\n\t// counter, base16, padded to 4 characters\n\tconst counter = ts.counter.toString(16).toUpperCase().padStart(4, '0');\n\t// node id padded to 16 characters\n\tconst node = ts.node.padStart(16, '0');\n\treturn `${dateString}-${counter}-${node}`;\n}\n\nexport function OLD_deserializeHlcTimestamp(clock: string): HLCTimestamp {\n\t// ISO string representation of the time\n\tconst dateString = clock.slice(0, 24);\n\tconst counter = clock.slice(25, 25 + 4);\n\tconst node = clock.slice(25 + 4 + 1);\n\n\tconst time = new Date(dateString).getTime();\n\tconst counterNum = parseInt(counter, 16);\n\n\tif (isNaN(time) || isNaN(counterNum)) {\n\t\tthrow new Error('invalid clock format');\n\t}\n\n\treturn {\n\t\ttime,\n\t\tcounter: counterNum,\n\t\tnode: node.slice(node.length - 7),\n\t};\n}\n\nexport function getTimestampSchemaVersion(timestamp: string): number {\n\treturn parseInt(timestamp.slice(0, VERSION_BLOCK_LENGTH), 36);\n}\n\nexport function compareTimestampSchemaVersions(a: string, b: string) {\n\treturn getTimestampSchemaVersion(a) - getTimestampSchemaVersion(b);\n}\n\nexport function getWallClockTime(timestamp: string): number {\n\treturn deserializeHlcTimestamp(timestamp.slice(VERSION_BLOCK_LENGTH)).time;\n}\n", "import { AuthorizationKey } from './authz.js';\nimport { ObjectIdentifier } from './oids.js';\nimport { applyPatch, Operation } from './operation.js';\nimport { PatchCreator } from './patch.js';\nimport { isRef } from './refs.js';\nimport { cloneDeep } from './utils.js';\n\nexport function getUndoOperations(\n\toid: ObjectIdentifier,\n\tinitial: any,\n\toperations: Operation[],\n\tgetNow: () => string,\n\tgetSubId?: () => string,\n\tauthz?: AuthorizationKey,\n): Operation[] {\n\tconst patchCreator = new PatchCreator(getNow, getSubId);\n\tif (initial === undefined || initial === null) {\n\t\t// if the initial state is nothing, then the undo is to delete everything.\n\t\t// there's nothing else to worry about!\n\t\treturn [\n\t\t\t{\n\t\t\t\toid,\n\t\t\t\ttimestamp: getNow(),\n\t\t\t\tdata: {\n\t\t\t\t\top: 'delete',\n\t\t\t\t},\n\t\t\t\tauthz,\n\t\t\t},\n\t\t];\n\t}\n\t// otherwise, traverse the operations one by one,\n\t// applying them, and using the prior state to determine\n\t// what the undo operation is.\n\tlet state = cloneDeep(initial);\n\tconst undoOperations: Operation[] = [];\n\tfor (const operation of operations) {\n\t\tconst undo = getUndoOperation(oid, state, operation, patchCreator, authz);\n\t\tundoOperations.unshift(...undo);\n\t\tapplyPatch(state, operation.data);\n\t}\n\treturn undoOperations;\n}\n\nfunction getUndoOperation(\n\toid: ObjectIdentifier,\n\tinitial: any,\n\toperation: Operation,\n\tpatchCreator: PatchCreator,\n\tauthz?: AuthorizationKey,\n): Operation[] {\n\tconst data = operation.data;\n\tswitch (data.op) {\n\t\tcase 'set':\n\t\t\tif (initial[data.name] === undefined) {\n\t\t\t\treturn patchCreator.createRemove(oid, data.name, authz);\n\t\t\t}\n\t\t\treturn patchCreator.createSet(oid, data.name, initial[data.name], authz);\n\t\tcase 'remove':\n\t\t\tif (initial[data.name] === undefined) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\treturn patchCreator.createSet(oid, data.name, initial[data.name], authz);\n\t\tcase 'list-insert':\n\t\t\tif (data.value === undefined && data.values?.length === 0) return [];\n\t\t\treturn patchCreator.createListDelete(\n\t\t\t\toid,\n\t\t\t\tdata.index,\n\t\t\t\tdata.value ? 1 : data.values?.length || 0,\n\t\t\t\tauthz,\n\t\t\t);\n\t\tcase 'list-delete':\n\t\t\treturn patchCreator.createListInsertMany(\n\t\t\t\toid,\n\t\t\t\tdata.index,\n\t\t\t\tinitial.slice(data.index, data.index + data.count),\n\t\t\t\tauthz,\n\t\t\t);\n\t\tcase 'list-move-by-ref':\n\t\t\treturn patchCreator.createListMoveByRef(\n\t\t\t\toid,\n\t\t\t\tdata.value,\n\t\t\t\tfindItemRefIndex(initial, data.value),\n\t\t\t\tauthz,\n\t\t\t);\n\t\tcase 'list-move-by-index':\n\t\t\treturn patchCreator.createListMoveByIndex(oid, data.to, data.from, authz);\n\t\tcase 'delete':\n\t\t\treturn patchCreator.createInitialize(initial, oid, authz, true);\n\t\tcase 'list-push':\n\t\t\treturn patchCreator.createListRemove(oid, data.value, 'last', authz);\n\t\tcase 'list-remove':\n\t\t\tif (data.only === 'last') {\n\t\t\t\tconst index = findItemRefIndex(initial, data.value, 0, 'backward');\n\t\t\t\tif (index === -1) {\n\t\t\t\t\t// if the value isn't in the list, then there's nothing to undo.\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\treturn patchCreator.createListInsert(oid, index, data.value, authz);\n\t\t\t} else if (data.only === 'first') {\n\t\t\t\tconst index = findItemRefIndex(initial, data.value);\n\t\t\t\tif (index === -1) {\n\t\t\t\t\t// if the value isn't in the list, then there's nothing to undo.\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\treturn patchCreator.createListInsert(oid, index, data.value, authz);\n\t\t\t} else {\n\t\t\t\t// find all instances of value and restore them at their\n\t\t\t\t// original index\n\t\t\t\tconst indexesOfValue = [];\n\t\t\t\tlet index = findItemRefIndex(initial, data.value);\n\t\t\t\twhile (index !== -1) {\n\t\t\t\t\tindexesOfValue.push(index);\n\t\t\t\t\tindex = findItemRefIndex(initial, data.value, index + 1);\n\t\t\t\t}\n\t\t\t\treturn indexesOfValue.flatMap((index) =>\n\t\t\t\t\tpatchCreator.createListInsert(oid, index, data.value, authz),\n\t\t\t\t);\n\t\t\t}\n\t\tcase 'list-add':\n\t\t\t// this one is kind of ambiguous. in theory the set may have\n\t\t\t// already included the value and so no change happened. but\n\t\t\t// basically we infer the intent is to remove what was meant\n\t\t\t// to be added by this change.\n\t\t\treturn patchCreator.createListRemove(oid, data.value, 'last', authz);\n\t\tcase 'list-set':\n\t\t\tif (initial[data.index] !== undefined) {\n\t\t\t\treturn patchCreator.createListSet(\n\t\t\t\t\toid,\n\t\t\t\t\tdata.index,\n\t\t\t\t\tinitial[data.index],\n\t\t\t\t\tauthz,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn patchCreator.createListDelete(oid, data.index, 1, authz);\n\t\tcase 'initialize':\n\t\t\treturn patchCreator.createDelete(oid, authz);\n\t\tcase 'touch':\n\t\t\treturn [];\n\t\tdefault:\n\t\t\tthrow new Error(`Cannot undo operation type: ${(data as any).op}`);\n\t}\n}\n\nfunction findItemRefIndex(\n\tlist: any[],\n\titem: any,\n\tfrom: number = 0,\n\tdir: 'forward' | 'backward' = 'forward',\n) {\n\tconst method = dir === 'forward' ? 'findIndex' : 'findLastIndex';\n\t// for object items, attempt to find the matching item by OID.\n\tif (isRef(item)) {\n\t\treturn list[method](\n\t\t\t(i, idx) => isRef(i) && i.id === item.id && idx >= from,\n\t\t);\n\t}\n\treturn list[method]((i, idx) => i === item && idx >= from);\n}\n", "/**\n * This exists since I'm a little anxious about using WeakRef in production\n * and want to be able to roll it back quickly to debug issues. Basically by adding\n * import { WeakRef } from 'FakeWeakRef' to the top of the file, we can switch back\n * to using a simple object reference.\n */\n\nexport class FakeWeakRef<T extends symbol | object> {\n\tconstructor(value: T) {\n\t\tthis.value = value;\n\t}\n\n\tvalue: T;\n\n\tderef(): T | undefined {\n\t\treturn this.value;\n\t}\n}\n", "import { EventSubscriber } from '@verdant-web/common';\n\ntype Undoable = () => Undoable | Promise<Undoable | null> | null;\n\nexport class UndoHistory extends EventSubscriber<{ change: () => void }> {\n\tprivate _undoable: Undoable[] = [];\n\tprivate _undone: Undoable[] = [];\n\n\tget canUndo() {\n\t\treturn this._undoable.length > 0;\n\t}\n\tget canRedo() {\n\t\treturn this._undone.length > 0;\n\t}\n\n\tget undoLength() {\n\t\treturn this._undoable.length;\n\t}\n\tget redoLength() {\n\t\treturn this._undone.length;\n\t}\n\n\tundo = async () => {\n\t\tconst next = this._undoable.pop();\n\t\tif (next) {\n\t\t\tconst redo = await next();\n\t\t\tif (redo) this._undone.push(redo);\n\t\t\tthis.emit('change');\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t};\n\n\tredo = async () => {\n\t\tconst next = this._undone.pop();\n\t\tif (next) {\n\t\t\tconst undo = await next();\n\t\t\tif (undo) this._undoable.push(undo);\n\t\t\tthis.emit('change');\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t};\n\n\taddUndo = (undoPoint: Undoable) => {\n\t\tthis._undoable.push(undoPoint);\n\t\tthis._undone = [];\n\t\tthis.emit('change');\n\t};\n\n\taddRedo = (redoPoint: Undoable) => {\n\t\tthis._undone.push(redoPoint);\n\t\tthis.emit('change');\n\t};\n\n\tclear = () => {\n\t\tthis._undoable = [];\n\t\tthis._undone = [];\n\t\tthis.emit('change');\n\t};\n}\n", "export type VerdantLogger = (\n\tlevel: 'debug' | 'info' | 'warn' | 'error' | 'critical',\n\t...args: any[]\n) => void;\n\nexport const noLogger = () => {};\n\nexport const makeLogger =\n\t(prefix?: string): VerdantLogger =>\n\t(level, ...args) => {\n\t\tif (level === 'critical') {\n\t\t\targs.unshift('[CRITICAL]');\n\t\t}\n\t\tif (prefix) {\n\t\t\targs.unshift(`[${prefix}]`);\n\t\t}\n\t\tif (level === 'critical') {\n\t\t\tconsole.error(...args);\n\t\t} else {\n\t\t\tconsole[level](...args);\n\t\t}\n\t};\n\nexport function debugLogger(prefix?: string): VerdantLogger {\n\tif (!localStorage.getItem('DEBUG')) {\n\t\treturn noLogger;\n\t}\n\treturn makeLogger(prefix);\n}\n", "export class Disposable {\n\tprivate _disposes: (() => void | Promise<void>)[] = [];\n\tprotected disposed = false;\n\n\tdispose = async () => {\n\t\tthis.disposed = true;\n\t\tawait Promise.all(\n\t\t\tthis._disposes.map(async (dispose) => {\n\t\t\t\ttry {\n\t\t\t\t\tawait dispose();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconsole.error('Error disposing', err);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t\tthis._disposes = [];\n\t};\n\n\tcompose = (disposable: { dispose: () => void | Promise<void> }) =>\n\t\tthis.addDispose(disposable.dispose.bind(disposable));\n\n\tprotected addDispose = (dispose: () => void | Promise<void>) => {\n\t\tthis._disposes.push(dispose);\n\t};\n}\n", "import { roughSizeOfObject } from '@verdant-web/common';\nimport { Context } from '../../internal.js';\n\nexport const globalIDB =\n\ttypeof window !== 'undefined' ? window.indexedDB : (undefined as any);\n\nexport function isAbortError(err: unknown) {\n\treturn err instanceof Error && err.name === 'AbortError';\n}\n\nexport function storeRequestPromise<T>(request: IDBRequest<T>) {\n\treturn new Promise<T>((resolve, reject) => {\n\t\trequest.onsuccess = () => {\n\t\t\tresolve(request.result);\n\t\t};\n\t\trequest.onerror = () => {\n\t\t\tif (request.error && isAbortError(request.error)) {\n\t\t\t\t// TODO: is this the right thing to do?\n\t\t\t\tresolve(request.result);\n\t\t\t} else {\n\t\t\t\treject(request.error);\n\t\t\t}\n\t\t};\n\t});\n}\n\nexport function cursorIterator<T>(\n\trequest: IDBRequest<IDBCursorWithValue | null>,\n\tcallback: (value: T | null) => boolean,\n) {\n\treturn new Promise<void>((resolve, reject) => {\n\t\trequest.onsuccess = () => {\n\t\t\tconst cursor = request.result;\n\t\t\tif (cursor) {\n\t\t\t\tif (callback(cursor.value)) {\n\t\t\t\t\tcursor.continue();\n\t\t\t\t} else {\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t};\n\t\trequest.onerror = () => {\n\t\t\tif (request.error && isAbortError(request.error)) {\n\t\t\t\tresolve();\n\t\t\t} else {\n\t\t\t\treject(request.error);\n\t\t\t}\n\t\t};\n\t});\n}\n\nexport function getSizeOfObjectStore(\n\tdatabase: IDBDatabase,\n\tstoreName: string,\n): Promise<{ count: number; size: number }> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst tx = database.transaction([storeName], 'readonly');\n\t\tconst store = tx.objectStore(storeName);\n\t\tconst cursorReq = store.openCursor();\n\t\tlet count = 0;\n\t\tlet size = 0;\n\t\tcursorReq.onsuccess = function (e) {\n\t\t\tconst cursor = cursorReq.result;\n\t\t\tif (cursor) {\n\t\t\t\tcount++;\n\t\t\t\tsize = size + roughSizeOfObject(cursor.value);\n\t\t\t\tcursor.continue();\n\t\t\t}\n\t\t};\n\t\tcursorReq.onerror = function (e) {\n\t\t\tif (cursorReq.error && isAbortError(cursorReq.error)) {\n\t\t\t\tresolve({\n\t\t\t\t\tcount: count,\n\t\t\t\t\tsize: size,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\treject(cursorReq.error);\n\t\t\t}\n\t\t};\n\t\ttx.oncomplete = function (e) {\n\t\t\tresolve({\n\t\t\t\tcount: count,\n\t\t\t\tsize: size,\n\t\t\t});\n\t\t};\n\t\ttx.onabort = function (e) {\n\t\t\treject(e);\n\t\t};\n\t\ttx.onerror = function (e) {\n\t\t\treject(e);\n\t\t};\n\t});\n}\n\nexport async function getSizesOfAllObjectStores(\n\tdatabase: IDBDatabase,\n): Promise<{ [storeName: string]: { count: number; size: number } }> {\n\tconst storeNames = Array.from(database.objectStoreNames);\n\tconst promises = storeNames.map(async (storeName) => {\n\t\tconst result = await getSizeOfObjectStore(database, storeName);\n\t\treturn { [storeName]: result };\n\t});\n\tconst results = await Promise.all(promises);\n\treturn results.reduce((acc, result_1) => {\n\t\treturn { ...acc, ...result_1 };\n\t}, {});\n}\n\nexport function getAllFromObjectStores(db: IDBDatabase, stores: string[]) {\n\tconst transaction = db.transaction(stores, 'readonly');\n\tconst promises = stores.map((store) => {\n\t\tconst objectStore = transaction.objectStore(store);\n\t\treturn storeRequestPromise(objectStore.getAll());\n\t});\n\treturn Promise.all(promises);\n}\n\nexport async function closeDatabase(db: IDBDatabase) {\n\tdb.close();\n\t// wait for microtask queue to clear\n\tawait new Promise<void>((resolve) => {\n\t\tresolve();\n\t});\n\tawait new Promise<void>((resolve) => {\n\t\tresolve();\n\t});\n}\n\nexport async function deleteAllDatabases(\n\tnamespace: string,\n\tenvironment: Context['environment'],\n) {\n\tconst req1 = environment.indexedDB.deleteDatabase(\n\t\t[namespace, 'meta'].join('_'),\n\t);\n\tconst req2 = environment.indexedDB.deleteDatabase(\n\t\t[namespace, 'collections'].join('_'),\n\t);\n\tawait Promise.all([\n\t\tnew Promise((resolve, reject) => {\n\t\t\treq1.onsuccess = resolve;\n\t\t\treq1.onerror = reject;\n\t\t}),\n\t\tnew Promise((resolve, reject) => {\n\t\t\treq2.onsuccess = resolve;\n\t\t\treq2.onerror = reject;\n\t\t}),\n\t]);\n\t// reload the page to reset any existing connections\n\tenvironment.location.reload();\n}\n\nexport function deleteDatabase(name: string, indexedDB = window.indexedDB) {\n\treturn storeRequestPromise(indexedDB.deleteDatabase(name));\n}\n\nexport async function getAllDatabaseNamesAndVersions(\n\tindexedDB: IDBFactory = window.indexedDB,\n) {\n\treturn indexedDB.databases();\n}\n\nexport function createAbortableTransaction(\n\tdb: IDBDatabase,\n\tstoreNames: string[],\n\tmode: 'readonly' | 'readwrite',\n\tabortSignal?: AbortSignal,\n\tlog?: (...args: any[]) => void,\n) {\n\ttry {\n\t\tconst tx = db.transaction(storeNames, mode);\n\t\tif (abortSignal) {\n\t\t\tconst abort = () => {\n\t\t\t\tlog?.('debug', 'aborting transaction');\n\t\t\t\ttry {\n\t\t\t\t\ttx.abort();\n\t\t\t\t\t(tx as any).__aborted = true;\n\t\t\t\t} catch (e) {\n\t\t\t\t\tlog?.('debug', 'aborting transaction failed', e);\n\t\t\t\t}\n\t\t\t};\n\t\t\tabortSignal.addEventListener('abort', abort);\n\t\t\ttx.addEventListener('error', () => {\n\t\t\t\tabortSignal.removeEventListener('abort', abort);\n\t\t\t});\n\t\t\ttx.addEventListener('complete', () => {\n\t\t\t\tabortSignal.removeEventListener('abort', abort);\n\t\t\t});\n\t\t}\n\t\treturn tx;\n\t} catch (err) {\n\t\tif (err instanceof Error && err.name === 'InvalidStateError') {\n\t\t\t// database is probably closing. it's ok, what can you do?\n\t\t\tlog?.('warn', 'Failed to create transaction, database is closing');\n\t\t\t// mock a Transaction so code can continue,\n\t\t\t// but doesn't do anything.\n\t\t\treturn {\n\t\t\t\tabort: () => {},\n\t\t\t\taddEventListener: () => {},\n\t\t\t\tobjectStore: () => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tadd: () => {},\n\t\t\t\t\t\tput: () => {},\n\t\t\t\t\t\tget: () => {},\n\t\t\t\t\t\tgetAll: () => {},\n\t\t\t\t\t\tdelete: () => {},\n\t\t\t\t\t\tclear: () => {},\n\t\t\t\t\t\topenCursor: () => {\n\t\t\t\t\t\t\tconst req = {\n\t\t\t\t\t\t\t\tonsuccess: () => {},\n\t\t\t\t\t\t\t\tonerror: (_: any) => {},\n\t\t\t\t\t\t\t\tresult: null,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\t\treq.onerror({} as any);\n\t\t\t\t\t\t\t}, 0);\n\t\t\t\t\t\t\treturn req;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tindex: () => {\n\t\t\t\t\t\t\tthrow new Error('Transaction is not active');\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\toncomplete: null,\n\t\t\t\tonerror: null,\n\t\t\t\tonabort: null,\n\t\t\t\terror: new Error('Transaction is not active') as any,\n\t\t\t\tcommit: () => {},\n\t\t\t\tdb,\n\t\t\t\tdispatchEvent: () => false,\n\t\t\t\tremoveEventListener: () => {},\n\t\t\t\tdurability: 'default',\n\t\t\t\tmode: 'readonly',\n\t\t\t\tobjectStoreNames: storeNames as any,\n\t\t\t\t__aborted: true,\n\t\t\t} as unknown as IDBTransaction;\n\t\t} else {\n\t\t\tthrow err;\n\t\t}\n\t}\n}\n\nexport function isTransactionAborted(tx: IDBTransaction) {\n\treturn (tx as any).__aborted;\n}\n\n/**\n * Deletes any existing database with name `toName` and\n * copies the index structure and all data\n * from `from` to a new database.\n *\n * Does NOT run Verdant migrations. Use to copy existing\n * data as-is.\n */\nexport async function overwriteDatabase(\n\tfrom: IDBDatabase,\n\ttoName: string,\n\tctx: Pick<Context, 'log'>,\n\tindexedDB = window.indexedDB,\n) {\n\tconst databases = await getAllDatabaseNamesAndVersions(indexedDB);\n\tif (databases.some((d) => d.name === toName)) {\n\t\tawait deleteDatabase(toName, indexedDB);\n\t\tctx.log('debug', 'Deleted existing database', toName);\n\t}\n\n\tconst to = await new Promise<IDBDatabase>((resolve, reject) => {\n\t\tctx.log(\n\t\t\t'debug',\n\t\t\t'Copying to database',\n\t\t\ttoName,\n\t\t\t'at',\n\t\t\tfrom.version,\n\t\t\t'from',\n\t\t\tfrom.name,\n\t\t);\n\t\tconst openRequest = indexedDB.open(toName, from.version);\n\t\topenRequest.onupgradeneeded = () => {\n\t\t\tctx.log(\n\t\t\t\t'debug',\n\t\t\t\t'Upgrading database',\n\t\t\t\ttoName,\n\t\t\t\t'to version',\n\t\t\t\tfrom.version,\n\t\t\t);\n\t\t\t// copy all indexes from original\n\t\t\tconst original = from;\n\t\t\tconst upgradeTx = openRequest.transaction;\n\t\t\tif (!upgradeTx) {\n\t\t\t\tthrow new Error('No transaction');\n\t\t\t}\n\t\t\tfor (const storeName of Array.from(original.objectStoreNames)) {\n\t\t\t\tctx.log('debug', 'Copying object store', storeName);\n\t\t\t\tconst originalObjectStore = original\n\t\t\t\t\t.transaction(storeName)\n\t\t\t\t\t.objectStore(storeName);\n\t\t\t\t// create object store\n\t\t\t\tupgradeTx.db.createObjectStore(storeName, {\n\t\t\t\t\tkeyPath: originalObjectStore.keyPath,\n\t\t\t\t\tautoIncrement: originalObjectStore.autoIncrement,\n\t\t\t\t});\n\t\t\t\tconst store = upgradeTx.objectStore(storeName);\n\t\t\t\tconst originalStore = original\n\t\t\t\t\t.transaction(storeName)\n\t\t\t\t\t.objectStore(storeName);\n\t\t\t\tfor (const index of Array.from(originalStore.indexNames)) {\n\t\t\t\t\tconst originalIndex = originalStore.index(index);\n\t\t\t\t\tctx.log('debug', 'Copying index', index);\n\t\t\t\t\tstore.createIndex(index, originalIndex.keyPath, {\n\t\t\t\t\t\tunique: originalIndex.unique,\n\t\t\t\t\t\tmultiEntry: originalIndex.multiEntry,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\topenRequest.onsuccess = () => {\n\t\t\tctx.log('debug', 'Opened reset database', toName);\n\t\t\tresolve(openRequest.result);\n\t\t};\n\t\topenRequest.onerror = () =>\n\t\t\treject(openRequest.error ?? new Error('Unknown database upgrade error'));\n\t});\n\n\t// only copy data to new database if there are object stores to\n\t// copy to\n\tif (to.objectStoreNames.length > 0) {\n\t\tconst records = await getAllFromObjectStores(\n\t\t\tfrom,\n\t\t\tArray.from(from.objectStoreNames),\n\t\t);\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tconst writeTx = to.transaction(\n\t\t\t\tArray.from(to.objectStoreNames),\n\t\t\t\t'readwrite',\n\t\t\t);\n\t\t\tfor (let i = 0; i < records.length; i++) {\n\t\t\t\tconst store = writeTx.objectStore(from.objectStoreNames[i]);\n\t\t\t\tfor (const record of records[i]) {\n\t\t\t\t\tstore.add(record);\n\t\t\t\t}\n\t\t\t}\n\t\t\twriteTx.oncomplete = () => resolve();\n\t\t\twriteTx.onerror = (ev) => {\n\t\t\t\tconst err =\n\t\t\t\t\twriteTx.error ??\n\t\t\t\t\t(ev.target as any).transaction?.error ??\n\t\t\t\t\tnew Error('Unknown error');\n\t\t\t\tctx.log('critical', 'Error copying data', err);\n\t\t\t\treject(err);\n\t\t\t};\n\t\t});\n\t}\n\n\tawait closeDatabase(to);\n}\n\nexport function openDatabase(\n\tname: string,\n\texpectedVersion: number,\n\tindexedDB: IDBFactory = window.indexedDB,\n) {\n\treturn new Promise<IDBDatabase>((resolve, reject) => {\n\t\tconst req = indexedDB.open(name, expectedVersion);\n\t\treq.onsuccess = () => {\n\t\t\tif (req.result.version !== expectedVersion) {\n\t\t\t\treq.result.close();\n\t\t\t\treject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t`Migration error: opened database version ${req.result.version} but expected version ${expectedVersion} for database ${name}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve(req.result);\n\t\t};\n\t\treq.onerror = () => {\n\t\t\treject(req.error);\n\t\t};\n\t\treq.onblocked = () => {\n\t\t\treject(new Error('Database blocked'));\n\t\t};\n\t\treq.onupgradeneeded = (event) => {\n\t\t\tconst db = req.result;\n\t\t\tif (db.version !== expectedVersion) {\n\t\t\t\tdb.close();\n\t\t\t\treject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t`Migration error: database version changed unexpectedly when reading current data. Expected ${expectedVersion}, got ${db.version}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\t});\n}\n\nexport function getMetadataDbName(namespace: string) {\n\treturn [namespace, 'meta'].join('_');\n}\n\nexport function getDocumentDbName(namespace: string) {\n\treturn [namespace, 'collections'].join('_');\n}\n\nexport function getNamespaceFromDatabaseInfo(info: IDBDatabaseInfo) {\n\treturn info.name?.split('_')[0];\n}\n", "import { Context } from '../../context/context.js';\nimport { Disposable } from '../../utils/Disposable.js';\nimport {\n\tcreateAbortableTransaction,\n\tisAbortError,\n\tisTransactionAborted,\n\tstoreRequestPromise,\n} from './util.js';\n\nexport class IdbService extends Disposable {\n\tprotected log?: Context['log'];\n\tprivate globalAbortController;\n\n\tconstructor(\n\t\tprotected db: IDBDatabase,\n\t\tprotected readonly ctx: Pick<Context, 'log' | 'environment'>,\n\t) {\n\t\tsuper();\n\t\tconst abortController = new AbortController();\n\t\tthis.globalAbortController = abortController;\n\t\t// FIXME: replace with event? I can't get this to work.\n\t\t// this.addDispose(abort);\n\t\tthis.db.addEventListener('versionchange', this.onVersionChange);\n\t\tthis.addDispose(() => {\n\t\t\tthis.db.removeEventListener('versionchange', this.onVersionChange);\n\t\t});\n\t}\n\n\tcreateTransaction = (\n\t\tstoreNames: string[],\n\t\topts?: {\n\t\t\tmode?: 'readonly' | 'readwrite';\n\t\t\tabort?: AbortSignal;\n\t\t},\n\t) => {\n\t\ttry {\n\t\t\tif (this.globalAbortController.signal.aborted) {\n\t\t\t\tthrow new Error('Global abort signal is already aborted');\n\t\t\t}\n\t\t\tconst tx = createAbortableTransaction(\n\t\t\t\tthis.db,\n\t\t\t\tstoreNames,\n\t\t\t\topts?.mode || 'readonly',\n\t\t\t\topts?.abort,\n\t\t\t\tthis.log,\n\t\t\t);\n\t\t\tthis.globalAbortController.signal.addEventListener('abort', tx.abort);\n\t\t\ttx.addEventListener('complete', () => {\n\t\t\t\tthis.globalAbortController.signal.removeEventListener(\n\t\t\t\t\t'abort',\n\t\t\t\t\ttx.abort,\n\t\t\t\t);\n\t\t\t});\n\t\t\ttx.addEventListener('error', () => {\n\t\t\t\tthis.globalAbortController.signal.removeEventListener(\n\t\t\t\t\t'abort',\n\t\t\t\t\ttx.abort,\n\t\t\t\t);\n\t\t\t});\n\t\t\treturn tx;\n\t\t} catch (err) {\n\t\t\tthis.log?.(\n\t\t\t\t'error',\n\t\t\t\t'Failed to create abortable transaction for store names',\n\t\t\t\tstoreNames,\n\t\t\t\terr,\n\t\t\t);\n\t\t\tthrow err;\n\t\t}\n\t};\n\n\trun = async <T = any>(\n\t\tstoreName: string,\n\t\tgetRequest: (store: IDBObjectStore) => IDBRequest<T>,\n\t\topts?: {\n\t\t\tmode?: 'readonly' | 'readwrite';\n\t\t\ttransaction?: IDBTransaction;\n\t\t\tabort?: AbortSignal;\n\t\t},\n\t): Promise<T> => {\n\t\tif (this.disposed || opts?.transaction?.error)\n\t\t\treturn Promise.resolve(undefined as any);\n\t\tconst tx = opts?.transaction || this.createTransaction([storeName], opts);\n\t\tif (isTransactionAborted(tx)) {\n\t\t\treturn Promise.resolve(undefined as any);\n\t\t}\n\t\tconst store = tx.objectStore(storeName);\n\t\tconst request = getRequest(store);\n\t\treturn storeRequestPromise<T>(request);\n\t};\n\n\trunAll = async <T>(\n\t\tstoreName: string,\n\t\tgetRequests: (store: IDBObjectStore) => IDBRequest<T>[],\n\t\topts?: {\n\t\t\tmode?: 'readonly' | 'readwrite';\n\t\t\ttransaction?: IDBTransaction;\n\t\t\tabort?: AbortSignal;\n\t\t},\n\t): Promise<T[]> => {\n\t\tif (this.disposed || opts?.transaction?.error) return Promise.resolve([]);\n\t\tif (opts?.transaction && isTransactionAborted(opts.transaction)) {\n\t\t\treturn Promise.resolve([]);\n\t\t}\n\t\tconst tx = opts?.transaction || this.createTransaction([storeName], opts);\n\t\tconst store = tx.objectStore(storeName);\n\t\tconst requests = getRequests(store);\n\t\treturn Promise.all(requests.map(storeRequestPromise));\n\t};\n\n\titerate = async <T>(\n\t\tstoreName: string,\n\t\tgetRequest: (\n\t\t\tstore: IDBObjectStore,\n\t\t) =>\n\t\t\t| IDBRequest<IDBCursorWithValue | null>\n\t\t\t| IDBRequest<IDBCursorWithValue | null>[],\n\t\titerator: (\n\t\t\tvalue: T,\n\t\t\tstore: IDBObjectStore,\n\t\t\tcursor: IDBCursorWithValue,\n\t\t) => boolean | void,\n\t\topts?: {\n\t\t\tmode?: 'readonly' | 'readwrite';\n\t\t\ttransaction?: IDBTransaction;\n\t\t\tabort?: AbortSignal;\n\t\t},\n\t): Promise<void> => {\n\t\tconst tx = opts?.transaction || this.createTransaction([storeName], opts);\n\t\tif (isTransactionAborted(tx)) {\n\t\t\treturn;\n\t\t}\n\t\tconst store = tx.objectStore(storeName);\n\t\tconst request = getRequest(store);\n\t\tif (Array.isArray(request)) {\n\t\t\treturn Promise.all(\n\t\t\t\trequest.map((req) => {\n\t\t\t\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\t\t\t\treq.onsuccess = () => {\n\t\t\t\t\t\t\tconst cursor = req.result;\n\t\t\t\t\t\t\tif (cursor) {\n\t\t\t\t\t\t\t\tconst stop = iterator(cursor.value, store, cursor);\n\t\t\t\t\t\t\t\tif (stop) {\n\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcursor.continue();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\treq.onerror = () => {\n\t\t\t\t\t\t\tif (req.error && isAbortError(req.error)) {\n\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treject(req.error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t}),\n\t\t\t).then(() => undefined);\n\t\t}\n\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\trequest.onsuccess = () => {\n\t\t\t\tconst cursor = request.result as IDBCursorWithValue | null;\n\t\t\t\tif (cursor) {\n\t\t\t\t\tconst stop = iterator(cursor.value, store, cursor);\n\t\t\t\t\tif (stop) {\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcursor.continue();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\t\t\trequest.onerror = () => {\n\t\t\t\tif (request.error && isAbortError(request.error)) {\n\t\t\t\t\tresolve();\n\t\t\t\t} else {\n\t\t\t\t\treject(request.error);\n\t\t\t\t}\n\t\t\t};\n\t\t});\n\t};\n\n\tclear = (storeName: string, transaction?: IDBTransaction) => {\n\t\treturn this.run<undefined>(storeName, (store) => store.clear(), {\n\t\t\tmode: 'readwrite',\n\t\t\ttransaction,\n\t\t});\n\t};\n\n\tprivate onVersionChange = (ev: IDBVersionChangeEvent) => {\n\t\tthis.log?.(\n\t\t\t'warn',\n\t\t\t`Another tab has requested a version change for ${this.db.name}`,\n\t\t);\n\t\tthis.db.close();\n\t\tif (typeof window !== 'undefined') {\n\t\t\ttry {\n\t\t\t\tthis.ctx.environment.location.reload();\n\t\t\t} catch (err) {\n\t\t\t\tthis.log?.('error', 'Failed to reload the page', err);\n\t\t\t}\n\t\t}\n\t};\n}\n", "import { FileData } from '@verdant-web/common';\nimport { Context } from '../../../internal.js';\nimport {\n\tAbstractTransaction,\n\tPersistedFileData,\n\tPersistenceFileDb,\n} from '../../interfaces.js';\nimport { IdbService } from '../IdbService.js';\nimport { getAllFromObjectStores, getSizeOfObjectStore } from '../util.js';\n\n/**\n * When stored in IDB, replace the file blob with an array buffer\n * since it's more compatible, and replace remote boolean with\n * a string since IDB doesn't support boolean indexes.\n */\nexport interface StoredFileData extends Omit<FileData, 'remote' | 'file'> {\n\tremote: 'true' | 'false';\n\tbuffer?: ArrayBuffer;\n\tdeletedAt: number | null;\n\ttimestamp?: string;\n}\n\nexport class IdbPersistenceFileDb\n\textends IdbService\n\timplements PersistenceFileDb\n{\n\tadd = async (file: FileData): Promise<void> => {\n\t\tlet buffer = file.file ? await fileToArrayBuffer(file.file) : undefined;\n\n\t\tawait this.run(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store.put({\n\t\t\t\t\tid: file.id,\n\t\t\t\t\t// IDB doesn't support boolean indexes\n\t\t\t\t\tremote: file.remote ? 'true' : 'false',\n\t\t\t\t\tdeletedAt: null,\n\t\t\t\t\tname: file.name,\n\t\t\t\t\ttype: file.type,\n\t\t\t\t\turl: file.url,\n\t\t\t\t\tbuffer,\n\t\t\t\t\ttimestamp: file.timestamp,\n\t\t\t\t} satisfies StoredFileData);\n\t\t\t},\n\t\t\t{\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t);\n\t};\n\tmarkUploaded = async (id: string): Promise<void> => {\n\t\tif (this.disposed) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst current = await this.getFileRaw(id);\n\n\t\tif (!current) {\n\t\t\tthis.ctx.log('error', 'Tried to mark unknown file as uploaded', id);\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.run(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store.put({\n\t\t\t\t\t...current,\n\t\t\t\t\tremote: 'true',\n\t\t\t\t} as StoredFileData);\n\t\t\t},\n\t\t\t{\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t);\n\t};\n\tget = async (fileId: string): Promise<PersistedFileData | null> => {\n\t\tconst raw = await this.getFileRaw(fileId);\n\t\tif (!raw) {\n\t\t\treturn null;\n\t\t}\n\t\treturn this.hydrateFileData(raw);\n\t};\n\tdelete = (fileId: string): Promise<void> => {\n\t\treturn this.run<undefined>(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store.delete(fileId);\n\t\t\t},\n\t\t\t{\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t);\n\t};\n\tmarkPendingDelete = async (fileId: string): Promise<void> => {\n\t\tconst current = await this.getFileRaw(fileId);\n\n\t\tif (!current) {\n\t\t\tthrow new Error('File is not in local database');\n\t\t}\n\n\t\tawait this.run(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store.put({\n\t\t\t\t\t...current,\n\t\t\t\t\tdeletedAt: Date.now(),\n\t\t\t\t} as StoredFileData);\n\t\t\t},\n\t\t\t{\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t);\n\t};\n\tlistUnsynced = async (): Promise<PersistedFileData[]> => {\n\t\tconst raw = await this.run<StoredFileData[]>(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store.index('remote').getAll('false');\n\t\t\t},\n\t\t\t{ mode: 'readonly' },\n\t\t);\n\t\treturn raw?.map(this.hydrateFileData) ?? [];\n\t};\n\tresetSyncedStatusSince = async (since: string | null): Promise<void> => {\n\t\tconst tx: IDBTransaction = this.createTransaction(['files'], {\n\t\t\tmode: 'readwrite',\n\t\t});\n\t\tconst raw = await this.run<StoredFileData[]>(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store.index('remote').getAll('true');\n\t\t\t},\n\t\t\t{ transaction: tx },\n\t\t);\n\n\t\tconst filtered = raw.filter(\n\t\t\t(file) => !file.timestamp || !since || file.timestamp > since,\n\t\t);\n\n\t\tawait Promise.all(\n\t\t\tfiltered.map((file) => {\n\t\t\t\treturn this.run(\n\t\t\t\t\t'files',\n\t\t\t\t\t(store) => {\n\t\t\t\t\t\treturn store.put({\n\t\t\t\t\t\t\t...file,\n\t\t\t\t\t\t\tremote: 'false',\n\t\t\t\t\t\t} as StoredFileData);\n\t\t\t\t\t},\n\t\t\t\t\t{ transaction: tx },\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\t};\n\titerateOverPendingDelete = (\n\t\titerator: (file: PersistedFileData, store: IDBObjectStore) => void,\n\t): Promise<void> => {\n\t\treturn this.iterate<StoredFileData>(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store\n\t\t\t\t\t.index('deletedAt')\n\t\t\t\t\t.openCursor(IDBKeyRange.lowerBound(0, true));\n\t\t\t},\n\t\t\t(value, store) => {\n\t\t\t\titerator(this.hydrateFileData(value), store);\n\t\t\t},\n\t\t\t{\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t);\n\t};\n\tgetAll = async (options?: {\n\t\ttransaction?: AbstractTransaction;\n\t}): Promise<PersistedFileData[]> => {\n\t\tconst [files] = await getAllFromObjectStores(this.db, ['files']);\n\t\treturn files.map(this.hydrateFileData);\n\t};\n\tstats = async (): Promise<{ size: { count: number; size: number } }> => {\n\t\treturn {\n\t\t\tsize: await getSizeOfObjectStore(this.db, 'files'),\n\t\t};\n\t};\n\tloadFileContents = async (file: FileData, ctx: Context): Promise<Blob> => {\n\t\tif (file.file) return file.file;\n\t\tif (file.localPath) {\n\t\t\tthrow new Error('Local file paths are not supported in browser');\n\t\t}\n\t\tif (file.url) {\n\t\t\tconst response = await ctx.environment.fetch(file.url);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Failed to download file ${file.url}: ${response.statusText}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn response.blob();\n\t\t}\n\t\tthrow new Error('File is missing url, file, and localPath');\n\t};\n\n\tprivate hydrateFileData = (raw: StoredFileData): PersistedFileData => {\n\t\t(raw as any).remote = raw.remote === 'true';\n\t\tconst buffer = raw.buffer;\n\t\tdelete raw.buffer;\n\t\t(raw as unknown as FileData).file = buffer\n\t\t\t? arrayBufferToBlob(buffer, raw.type, raw.name)\n\t\t\t: undefined;\n\t\treturn raw as unknown as PersistedFileData;\n\t};\n\n\tprivate getFileRaw = async (\n\t\tid: string,\n\t\t{ transaction }: { transaction?: AbstractTransaction } = {},\n\t): Promise<StoredFileData | undefined> => {\n\t\tif (this.disposed) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst raw = await this.run<StoredFileData>(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store.get(id);\n\t\t\t},\n\t\t\t{ mode: 'readonly', transaction: transaction as IDBTransaction },\n\t\t);\n\t\tif (!raw) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn raw;\n\t};\n}\n\nexport function arrayBufferToBlob(\n\tbuffer: ArrayBuffer,\n\ttype: string,\n\tname?: string,\n) {\n\treturn new File([new Blob([buffer], { type })], name ?? 'blob', {\n\t\ttype,\n\t});\n}\n\nfunction fileToArrayBuffer(file: File | Blob): Promise<ArrayBuffer> {\n\t// special case for testing...\n\tif ('__testReadBuffer' in file) {\n\t\treturn Promise.resolve<any>(file.__testReadBuffer);\n\t}\n\treturn new Promise<ArrayBuffer>((resolve, reject) => {\n\t\tconst reader = new FileReader();\n\t\treader.onload = () => {\n\t\t\tresolve(reader.result as ArrayBuffer);\n\t\t};\n\t\treader.onerror = reject;\n\t\treader.readAsArrayBuffer(file);\n\t});\n}\n", "import {\n\tcreateCompoundIndexValue,\n\tcreateLowerBoundIndexValue,\n\tcreateUpperBoundIndexValue,\n\tDocumentBaseline,\n\tgetLegacyDotOidSubIdRange,\n\tgetOidRoot,\n\tgetOidSubIdRange,\n\tObjectIdentifier,\n} from '@verdant-web/common';\nimport { ContextWithoutPersistence } from '../../../context/context.js';\nimport {\n\tAbstractTransaction,\n\tAckInfo,\n\tClientOperation,\n\tCommonQueryOptions,\n\tIterator,\n\tLocalReplicaInfo,\n\tPersistenceMetadataDb,\n} from '../../interfaces.js';\nimport { IdbService } from '../IdbService.js';\nimport { closeDatabase, getSizeOfObjectStore } from '../util.js';\n\nexport type StoredClientOperation = ClientOperation & {\n\t/** This acts as the primary key */\n\toid_timestamp: string;\n\tl_t: string;\n\td_t: string;\n};\n\nexport type StoredSchema = {\n\ttype: 'schema';\n\tschema: string;\n};\n\nexport class IdbMetadataDb\n\textends IdbService\n\timplements PersistenceMetadataDb<IDBTransaction>\n{\n\tconstructor(db: IDBDatabase, ctx: ContextWithoutPersistence) {\n\t\tsuper(db, ctx);\n\t\tthis.addDispose(() => {\n\t\t\tthis.ctx.log('info', `Closing metadata DB for`, ctx.namespace);\n\t\t\treturn closeDatabase(db);\n\t\t});\n\t}\n\n\ttransaction = async <T>(\n\t\topts: {\n\t\t\tmode?: 'readwrite' | 'readonly';\n\t\t\tstoreNames: string[];\n\t\t\tabort?: AbortSignal;\n\t\t},\n\t\tprocedure: (tx: IDBTransaction) => Promise<T>,\n\t) => {\n\t\tconst tx = this.createTransaction(opts.storeNames, {\n\t\t\tmode: opts.mode,\n\t\t\tabort: opts.abort,\n\t\t});\n\t\tconst result = await procedure(tx);\n\t\treturn result;\n\t};\n\n\tgetAckInfo = async (): Promise<AckInfo> => {\n\t\tconst result = await this.run<AckInfo>('info', (store) => store.get('ack'));\n\t\tif (result) {\n\t\t\treturn result;\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tglobalAckTimestamp: null,\n\t\t\t};\n\t\t}\n\t};\n\n\tsetGlobalAck = async (ack: string): Promise<void> => {\n\t\tawait this.run(\n\t\t\t'info',\n\t\t\t(store) => store.put({ type: 'ack', globalAckTimestamp: ack }),\n\t\t\t{ mode: 'readwrite' },\n\t\t);\n\t};\n\n\tgetLocalReplica = async (\n\t\topts?: CommonQueryOptions,\n\t): Promise<LocalReplicaInfo | undefined> => {\n\t\treturn this.run<LocalReplicaInfo | undefined>(\n\t\t\t'info',\n\t\t\t(store) => store.get('localReplicaInfo'),\n\t\t\topts,\n\t\t);\n\t};\n\n\tupdateLocalReplica = async (\n\t\tdata: LocalReplicaInfo,\n\t\topts?: CommonQueryOptions,\n\t): Promise<void> => {\n\t\ttry {\n\t\t\tawait this.run(\n\t\t\t\t'info',\n\t\t\t\t(store) =>\n\t\t\t\t\tstore.put({\n\t\t\t\t\t\t...data,\n\t\t\t\t\t\ttype: 'localReplicaInfo',\n\t\t\t\t\t}),\n\t\t\t\t{\n\t\t\t\t\tmode: 'readwrite',\n\t\t\t\t\ttransaction: opts?.transaction,\n\t\t\t\t},\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tthis.ctx.log('critical', 'Error updating local replica', data, e);\n\t\t\tthrow e;\n\t\t}\n\t};\n\n\titerateDocumentBaselines = async (\n\t\trootOid: string,\n\t\titerator: (baseline: DocumentBaseline) => void,\n\t\topts?: CommonQueryOptions,\n\t): Promise<void> => {\n\t\tawait this.iterate(\n\t\t\t'baselines',\n\t\t\t(store) => {\n\t\t\t\tconst root = getOidRoot(rootOid);\n\t\t\t\tconst [start, end] = getOidSubIdRange(rootOid);\n\t\t\t\t// FIXME: get rid of legacy dot OIDs...\n\t\t\t\tconst [dotStart, dotEnd] = getLegacyDotOidSubIdRange(rootOid);\n\t\t\t\treturn [\n\t\t\t\t\tstore.openCursor(IDBKeyRange.only(root)),\n\t\t\t\t\tstore.openCursor(IDBKeyRange.bound(start, end, false, false)),\n\t\t\t\t\tstore.openCursor(IDBKeyRange.bound(dotStart, dotEnd, false, false)),\n\t\t\t\t];\n\t\t\t},\n\t\t\titerator,\n\t\t\topts,\n\t\t);\n\t};\n\n\titerateCollectionBaselines = async (\n\t\tcollection: string,\n\t\titerator: (baseline: DocumentBaseline) => void,\n\t\topts?: CommonQueryOptions,\n\t): Promise<void> => {\n\t\tawait this.iterate(\n\t\t\t'baselines',\n\t\t\t(store) => {\n\t\t\t\treturn [\n\t\t\t\t\tstore.openCursor(\n\t\t\t\t\t\tIDBKeyRange.bound(collection, collection + '\\uffff', false, false),\n\t\t\t\t\t),\n\t\t\t\t];\n\t\t\t},\n\t\t\titerator,\n\t\t\topts,\n\t\t);\n\t};\n\n\titerateAllBaselines = async (\n\t\titerator: Iterator<DocumentBaseline>,\n\t\topts: CommonQueryOptions,\n\t): Promise<void> => {\n\t\tawait this.iterate(\n\t\t\t'baselines',\n\t\t\t(store) => store.index('timestamp').openCursor(),\n\t\t\titerator,\n\t\t\topts,\n\t\t);\n\t};\n\n\tgetBaseline = (\n\t\toid: string,\n\t\topts?: CommonQueryOptions,\n\t): Promise<DocumentBaseline> => {\n\t\treturn this.run<DocumentBaseline>(\n\t\t\t'baselines',\n\t\t\t(store) => store.get(oid),\n\t\t\topts,\n\t\t);\n\t};\n\n\tsetBaselines = async (\n\t\tbaselines: DocumentBaseline[],\n\t\topts: CommonQueryOptions = writeOpts,\n\t): Promise<void> => {\n\t\tawait this.runAll<any>(\n\t\t\t'baselines',\n\t\t\t(store) => baselines.map((b) => store.put(b)),\n\t\t\topts,\n\t\t);\n\t};\n\n\tdeleteBaseline = async (\n\t\toid: string,\n\t\topts: CommonQueryOptions = writeOpts,\n\t): Promise<void> => {\n\t\tawait this.run('baselines', (store) => store.delete(oid), opts);\n\t};\n\n\titerateDocumentOperations = (\n\t\trootOid: string,\n\t\titerator: (op: StoredClientOperation) => void,\n\t\topts?: CommonQueryOptions & { to?: string | null },\n\t): Promise<void> => {\n\t\treturn this.iterate<StoredClientOperation>(\n\t\t\t'operations',\n\t\t\t(store) => {\n\t\t\t\tconst index = store.index('d_t');\n\t\t\t\tconst start = createLowerBoundIndexValue(rootOid);\n\t\t\t\tconst end = opts?.to\n\t\t\t\t\t? createCompoundIndexValue(rootOid, opts.to)\n\t\t\t\t\t: createUpperBoundIndexValue(rootOid);\n\n\t\t\t\tconst range = IDBKeyRange.bound(start, end, false, false);\n\t\t\t\treturn index.openCursor(range);\n\t\t\t},\n\t\t\titerator,\n\t\t\topts,\n\t\t);\n\t};\n\n\titerateEntityOperations = (\n\t\toid: string,\n\t\titerator: (op: StoredClientOperation) => void,\n\t\topts?: CommonQueryOptions & { to?: string | null },\n\t): Promise<void> => {\n\t\t// NOTE: this is simplified from original impl.\n\t\t// perhaps I missed some nuance as to why it was\n\t\t// so complex before?\n\n\t\treturn this.iterate<StoredClientOperation>(\n\t\t\t'operations',\n\t\t\t(store) => {\n\t\t\t\tconst start = createLowerBoundIndexValue(oid);\n\t\t\t\tconst end = opts?.to\n\t\t\t\t\t? createCompoundIndexValue(oid, opts.to)\n\t\t\t\t\t: createUpperBoundIndexValue(oid);\n\n\t\t\t\tconst range = IDBKeyRange.bound(start, end, false, false);\n\t\t\t\treturn store.openCursor(range);\n\t\t\t},\n\t\t\titerator,\n\t\t\topts,\n\t\t);\n\t};\n\n\tdeleteEntityOperations = (\n\t\toid: string,\n\t\topts: CommonQueryOptions & { to: string | null },\n\t): Promise<void> => {\n\t\treturn this.iterate<StoredClientOperation>(\n\t\t\t'operations',\n\t\t\t(store) => {\n\t\t\t\tconst start = createLowerBoundIndexValue(oid);\n\t\t\t\tconst end = opts?.to\n\t\t\t\t\t? createCompoundIndexValue(oid, opts.to)\n\t\t\t\t\t: createUpperBoundIndexValue(oid);\n\n\t\t\t\tconst range = IDBKeyRange.bound(start, end, false, false);\n\t\t\t\treturn store.openCursor(range);\n\t\t\t},\n\t\t\t(op, store) => {\n\t\t\t\tstore.delete(op.oid_timestamp);\n\t\t\t},\n\t\t\topts,\n\t\t);\n\t};\n\n\titerateCollectionOperations = (\n\t\tcollection: string,\n\t\titerator: (op: StoredClientOperation) => void,\n\t\topts?: CommonQueryOptions,\n\t): Promise<void> => {\n\t\treturn this.iterate(\n\t\t\t'operations',\n\t\t\t(store) => {\n\t\t\t\treturn store.openCursor(\n\t\t\t\t\tIDBKeyRange.bound(collection, collection + '\\uffff', false, false),\n\t\t\t\t\t'next',\n\t\t\t\t);\n\t\t\t},\n\t\t\titerator,\n\t\t\topts,\n\t\t);\n\t};\n\n\titerateLocalOperations = (\n\t\titerator: (op: StoredClientOperation) => void,\n\t\topts?: CommonQueryOptions & {\n\t\t\tafter?: string | null;\n\t\t},\n\t): Promise<void> => {\n\t\treturn this.iterate(\n\t\t\t'operations',\n\t\t\t(store) => {\n\t\t\t\tconst start = opts?.after\n\t\t\t\t\t? createCompoundIndexValue(true, opts.after)\n\t\t\t\t\t: createLowerBoundIndexValue(true);\n\t\t\t\tconst end = createUpperBoundIndexValue(true);\n\t\t\t\tconst index = store.index('l_t');\n\t\t\t\treturn index.openCursor(\n\t\t\t\t\t// NOTE: differs from original impl -- last arg is 'false' instead of 'true'\n\t\t\t\t\tIDBKeyRange.bound(start, end, !!opts?.after, false),\n\t\t\t\t\t'next',\n\t\t\t\t);\n\t\t\t},\n\t\t\titerator,\n\t\t);\n\t};\n\n\titerateAllOperations = (\n\t\titerator: (op: StoredClientOperation) => void,\n\t\topts?: CommonQueryOptions & {\n\t\t\tbefore?: string | null;\n\t\t\tfrom?: string | null;\n\t\t},\n\t): Promise<void> => {\n\t\treturn this.iterate(\n\t\t\t'operations',\n\t\t\t(store) => {\n\t\t\t\tconst start = opts?.from\n\t\t\t\t\t? createLowerBoundIndexValue(opts.from)\n\t\t\t\t\t: undefined;\n\t\t\t\tconst end = opts?.before\n\t\t\t\t\t? createUpperBoundIndexValue(opts.before)\n\t\t\t\t\t: createLowerBoundIndexValue(true);\n\t\t\t\tconst range =\n\t\t\t\t\tstart && end\n\t\t\t\t\t\t? IDBKeyRange.bound(start, end, false, true)\n\t\t\t\t\t\t: start\n\t\t\t\t\t\t\t? IDBKeyRange.lowerBound(start, false)\n\t\t\t\t\t\t\t: end\n\t\t\t\t\t\t\t\t? IDBKeyRange.upperBound(end, true)\n\t\t\t\t\t\t\t\t: undefined;\n\t\t\t\treturn store.index('timestamp').openCursor(range, 'next');\n\t\t\t},\n\t\t\titerator,\n\t\t\topts,\n\t\t);\n\t};\n\n\taddOperations = async (\n\t\tops: StoredClientOperation[],\n\t\topts: CommonQueryOptions = writeOpts,\n\t): Promise<ObjectIdentifier[]> => {\n\t\tlet affected = new Set<ObjectIdentifier>();\n\t\tawait this.runAll(\n\t\t\t'operations',\n\t\t\t(store) =>\n\t\t\t\tops.map((op) => {\n\t\t\t\t\taffected.add(getOidRoot(op.oid));\n\t\t\t\t\treturn store.put(this.addOperationIndexes(op));\n\t\t\t\t}),\n\t\t\topts,\n\t\t);\n\t\treturn Array.from(affected);\n\t};\n\n\treset = async ({\n\t\tclearReplica,\n\t\ttransaction,\n\t}: {\n\t\tclearReplica?: boolean;\n\t\ttransaction?: AbstractTransaction;\n\t} = {}): Promise<void> => {\n\t\tconst tx =\n\t\t\t(transaction as IDBTransaction) ||\n\t\t\tthis.createTransaction(['info', 'operations', 'baselines'], {\n\t\t\t\tmode: 'readwrite',\n\t\t\t});\n\t\tawait Promise.all([\n\t\t\tthis.resetLocalReplica(tx, clearReplica),\n\t\t\tthis.resetBaselines(tx),\n\t\t\tthis.resetOperations(tx),\n\t\t]);\n\t};\n\n\tstats = async (): Promise<{\n\t\toperationsSize: { count: number; size: number };\n\t\tbaselinesSize: { count: number; size: number };\n\t}> => {\n\t\tconst ops = await getSizeOfObjectStore(this.db, 'operations');\n\t\tconst baselines = await getSizeOfObjectStore(this.db, 'baselines');\n\t\treturn { operationsSize: ops, baselinesSize: baselines };\n\t};\n\n\tprivate resetLocalReplica = async (tx: IDBTransaction, clear = false) => {\n\t\tif (clear) {\n\t\t\treturn this.run('info', (store) => store.delete('localReplicaInfo'), {\n\t\t\t\tmode: 'readwrite',\n\t\t\t\ttransaction: tx,\n\t\t\t});\n\t\t} else {\n\t\t\tconst localInfo = await this.getLocalReplica({\n\t\t\t\ttransaction: tx,\n\t\t\t});\n\t\t\tif (localInfo) {\n\t\t\t\tlocalInfo.ackedLogicalTime = null;\n\t\t\t\tlocalInfo.lastSyncedLogicalTime = null;\n\t\t\t\tawait this.run(\n\t\t\t\t\t'info',\n\t\t\t\t\t(store) =>\n\t\t\t\t\t\tstore.put({\n\t\t\t\t\t\t\t...localInfo,\n\t\t\t\t\t\t\ttype: 'localReplicaInfo',\n\t\t\t\t\t\t}),\n\t\t\t\t\t{\n\t\t\t\t\t\tmode: 'readwrite',\n\t\t\t\t\t\ttransaction: tx,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate resetBaselines = async (tx: IDBTransaction) => {\n\t\treturn this.clear('baselines', tx);\n\t};\n\n\tprivate resetOperations = async (tx: IDBTransaction) => {\n\t\treturn this.clear('operations', tx);\n\t};\n\n\tprivate addOperationIndexes = (\n\t\top: ClientOperation,\n\t): StoredClientOperation => {\n\t\treturn {\n\t\t\t...op,\n\t\t\toid_timestamp: createCompoundIndexValue(op.oid, op.timestamp) as string,\n\t\t\tl_t: createCompoundIndexValue(op.isLocal, op.timestamp) as string,\n\t\t\td_t: createCompoundIndexValue(getOidRoot(op.oid), op.timestamp) as string,\n\t\t};\n\t};\n}\n\nconst writeOpts = { mode: 'readwrite' } as const;\n", "import { replaceLegacyOidsInObject } from '@verdant-web/common';\nimport { getMetadataDbName } from '../util.js';\nimport { Context } from '../../../context/context.js';\n\nconst migrations = [version1, version2, version3, version4, version5, version6];\nexport const CURRENT_METADATA_VERSION = migrations.length;\n\nexport function openMetadataDatabase({\n\tindexedDB = window.indexedDB,\n\tnamespace,\n\tlog,\n}: {\n\tindexedDB?: IDBFactory;\n\tnamespace: string;\n\tlog?: Context['log'];\n}): Promise<{ wasInitialized: boolean; db: IDBDatabase }> {\n\treturn new Promise<{ wasInitialized: boolean; db: IDBDatabase }>(\n\t\t(resolve, reject) => {\n\t\t\tconst request = indexedDB.open(\n\t\t\t\tgetMetadataDbName(namespace),\n\t\t\t\tCURRENT_METADATA_VERSION,\n\t\t\t);\n\t\t\tlet wasInitialized = false;\n\t\t\trequest.onupgradeneeded = async (event) => {\n\t\t\t\tconst db = request.result;\n\t\t\t\tconst tx = request.transaction!;\n\n\t\t\t\tconst toRun = migrations.slice(event.oldVersion);\n\t\t\t\tfor (const migration of toRun) {\n\t\t\t\t\tawait migration(db, tx);\n\t\t\t\t}\n\n\t\t\t\tawait new Promise((resolve, reject) => {\n\t\t\t\t\ttx.addEventListener('complete', resolve);\n\t\t\t\t\ttx.addEventListener('error', reject);\n\t\t\t\t});\n\n\t\t\t\tif (!event.oldVersion) {\n\t\t\t\t\twasInitialized = true;\n\t\t\t\t}\n\t\t\t};\n\t\t\trequest.onerror = () => {\n\t\t\t\tconsole.error('Error opening database', request.error);\n\t\t\t\treject(request.error);\n\t\t\t};\n\t\t\trequest.onsuccess = () => {\n\t\t\t\tresolve({ db: request.result, wasInitialized });\n\t\t\t};\n\t\t},\n\t);\n}\n\nasync function version1(db: IDBDatabase, tx: IDBTransaction) {\n\tconst baselinesStore = db.createObjectStore('baselines', {\n\t\tkeyPath: 'oid',\n\t});\n\tconst operationsStore = db.createObjectStore('operations', {\n\t\tkeyPath: 'oid_timestamp',\n\t});\n\tconst infoStore = db.createObjectStore('info', { keyPath: 'type' });\n\tbaselinesStore.createIndex('timestamp', 'timestamp');\n\toperationsStore.createIndex('isLocal_timestamp', 'isLocal_timestamp');\n\toperationsStore.createIndex('documentOid_timestamp', 'documentOid_timestamp');\n}\n\n/**\n * 1 -> 2 changes:\n *\n * Consolidate compound index names:\n *\n * Operations:\n * - isLocal_timestamp -> l_t\n * - documentOid_timestamp -> d_t\n */\nasync function version2(db: IDBDatabase, tx: IDBTransaction) {\n\tconst operations = tx.objectStore('operations');\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst cursorReq = operations.openCursor();\n\t\tcursorReq.onsuccess = () => {\n\t\t\t// rename the consolidated fields\n\t\t\tconst cursor = cursorReq.result;\n\t\t\tif (cursor) {\n\t\t\t\tconst { isLocal_timestamp, documentOid_timestamp, ...value } =\n\t\t\t\t\tcursor.value;\n\t\t\t\tcursor.update({\n\t\t\t\t\t...value,\n\t\t\t\t\tl_t: isLocal_timestamp,\n\t\t\t\t\td_t: documentOid_timestamp,\n\t\t\t\t});\n\t\t\t\tcursor.continue();\n\t\t\t} else {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t};\n\t\tcursorReq.onerror = (event) => {\n\t\t\treject(cursorReq.error);\n\t\t};\n\t});\n\t// remove the old indexes\n\toperations.deleteIndex('isLocal_timestamp');\n\toperations.deleteIndex('documentOid_timestamp');\n\t// create the new indexes\n\toperations.createIndex('l_t', 'l_t', { unique: false });\n\toperations.createIndex('o_t', 'o_t', { unique: false });\n\toperations.createIndex('d_t', 'd_t', { unique: false });\n}\n\n/**\n * 2 -> 3 changes:\n *\n * Add timestamp index to operations\n */\nasync function version3(db: IDBDatabase, tx: IDBTransaction) {\n\tconst operations = tx.objectStore('operations');\n\toperations.createIndex('timestamp', 'timestamp');\n}\n\n/**\n * 3 -> 4 changes:\n * Add files store\n */\nasync function version4(db: IDBDatabase, tx: IDBTransaction) {\n\tconst files = db.createObjectStore('files', {\n\t\tkeyPath: 'id',\n\t});\n\tfiles.createIndex('remote', 'remote');\n\tfiles.createIndex('deletedAt', 'deletedAt');\n}\n\n/**\n * 4 -> 5 changes:\n * replace legacy OIDs\n */\nasync function version5(db: IDBDatabase, tx: IDBTransaction) {\n\t// rewrites all baselines and operations to replace legacy OIDs\n\t// with new ones.\n\tconst operations = tx.objectStore('operations');\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst cursorReq = operations.openCursor();\n\t\tcursorReq.onsuccess = () => {\n\t\t\tconst cursor = cursorReq.result;\n\t\t\tif (cursor) {\n\t\t\t\tconst converted = replaceLegacyOidsInObject(cursor.value);\n\t\t\t\t// conversion may change the primary key, so we need to put the\n\t\t\t\t// object back to the store\n\t\t\t\tif (converted.oid_timestamp !== cursor.primaryKey) {\n\t\t\t\t\tcursor.delete();\n\t\t\t\t\toperations.put(converted);\n\t\t\t\t} else {\n\t\t\t\t\tcursor.update(converted);\n\t\t\t\t}\n\t\t\t\tcursor.continue();\n\t\t\t} else {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t};\n\t\tcursorReq.onerror = (event) => {\n\t\t\treject(cursorReq.error);\n\t\t};\n\t});\n\tconst baselines = tx.objectStore('baselines');\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst cursorReq = baselines.openCursor();\n\t\tcursorReq.onsuccess = () => {\n\t\t\tconst cursor = cursorReq.result;\n\t\t\tif (cursor) {\n\t\t\t\tconst converted = replaceLegacyOidsInObject(cursor.value);\n\t\t\t\tif (converted.oid !== cursor.primaryKey) {\n\t\t\t\t\tcursor.delete();\n\t\t\t\t\tbaselines.put(converted);\n\t\t\t\t} else {\n\t\t\t\t\tcursor.update(converted);\n\t\t\t\t}\n\t\t\t\tcursor.continue();\n\t\t\t} else {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t};\n\t\tcursorReq.onerror = (event) => {\n\t\t\treject(cursorReq.error);\n\t\t};\n\t});\n}\n\n// version 5->6: add timestamp to file metadata\nasync function version6(db: IDBDatabase, tx: IDBTransaction) {\n\tconst files = tx.objectStore('files');\n\tfiles.createIndex('timestamp', 'timestamp');\n}\n", "import {\n\tassert,\n\tCollectionCompoundIndexFilter,\n\tCollectionFilter,\n\tcreateCompoundIndexValue,\n\tcreateLowerBoundIndexValue,\n\tcreateUpperBoundIndexValue,\n\tisMatchIndexFilter,\n\tisRangeIndexFilter,\n\tisSortIndexFilter,\n\tisStartsWithIndexFilter,\n\tMatchCollectionIndexFilter,\n\tRangeCollectionIndexFilter,\n\tsanitizeIndexValue,\n\tSortIndexFilter,\n\tStartsWithIndexFilter,\n\tStorageSchema,\n} from '@verdant-web/common';\n\nconst matchIndexToIdbKeyRange = (filter: MatchCollectionIndexFilter) => {\n\treturn IDBKeyRange.only(sanitizeIndexValue(filter.equals));\n};\n\nconst sortIndexToIdbKeyRange = (filter: SortIndexFilter) => {\n\treturn undefined;\n};\n\nconst rangeIndexToIdbKeyRange = (filter: RangeCollectionIndexFilter) => {\n\tconst lower = filter.gte || filter.gt;\n\tconst upper = filter.lte || filter.lt;\n\tif (lower === upper) {\n\t\treturn IDBKeyRange.only(sanitizeIndexValue(lower));\n\t}\n\tif (!lower) {\n\t\treturn IDBKeyRange.upperBound(sanitizeIndexValue(upper), !!filter.lt);\n\t} else if (!upper) {\n\t\treturn IDBKeyRange.lowerBound(sanitizeIndexValue(lower), !!filter.gt);\n\t} else {\n\t\treturn IDBKeyRange.bound(\n\t\t\tsanitizeIndexValue(lower),\n\t\t\tsanitizeIndexValue(upper),\n\t\t\t!!filter.gt,\n\t\t\t!!filter.lt,\n\t\t);\n\t}\n};\n\nconst compoundIndexToIdbKeyRange = (\n\t// FIXME:\n\tschema: any,\n\tcollection: string,\n\tfilter: CollectionCompoundIndexFilter,\n) => {\n\t// validate the usage of the compound index:\n\t// - all match fields must be contiguous at the start of the compound order\n\tconst indexDefinition =\n\t\tschema.collections[collection].compounds[filter.where];\n\tassert(\n\t\tindexDefinition,\n\t\t`Index ${filter.where} does not exist on collection ${collection}`,\n\t);\n\tconst matchedKeys = Object.keys(filter.match).sort(\n\t\t(a, b) => indexDefinition.of.indexOf(a) - indexDefinition.of.indexOf(b),\n\t);\n\tfor (const key of matchedKeys) {\n\t\tif (indexDefinition.of.indexOf(key) !== matchedKeys.indexOf(key)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Compound index ${filter.where} does not have ${key} at the start of its order`,\n\t\t\t);\n\t\t}\n\t}\n\n\tconst matchedValues = matchedKeys.map(\n\t\t(key) => filter.match[key as keyof typeof filter.match] as string | number,\n\t);\n\n\t// special case: all match fields are specified - we don't need a range\n\t// query, just a single key query\n\tif (matchedKeys.length === indexDefinition.of.length) {\n\t\treturn IDBKeyRange.only(createCompoundIndexValue(...matchedValues));\n\t}\n\n\t// create our bounds for the matched values\n\tconst lower = createLowerBoundIndexValue(...matchedValues);\n\tconst upper = createUpperBoundIndexValue(...matchedValues);\n\treturn IDBKeyRange.bound(lower, upper);\n};\n\nfunction startsWithIndexToIdbKeyRange(filter: StartsWithIndexFilter) {\n\tconst lower = filter.startsWith;\n\tconst upper = filter.startsWith + '\\uffff';\n\treturn IDBKeyRange.bound(lower, upper);\n}\n\nexport function getRange(\n\tschema: StorageSchema,\n\tcollection: string,\n\tindex?: CollectionFilter,\n) {\n\tif (!index) return undefined;\n\tif (isRangeIndexFilter(index)) return rangeIndexToIdbKeyRange(index);\n\tif (isMatchIndexFilter(index)) return matchIndexToIdbKeyRange(index);\n\tif (isSortIndexFilter(index)) return sortIndexToIdbKeyRange(index);\n\tif (isStartsWithIndexFilter(index))\n\t\treturn startsWithIndexToIdbKeyRange(index);\n\treturn compoundIndexToIdbKeyRange(schema, collection, index);\n}\n", "import {\n\tCollectionFilter,\n\tcreateOid,\n\tdecomposeOid,\n\tgetIndexValues,\n\tObjectIdentifier,\n} from '@verdant-web/common';\nimport { ContextWithoutPersistence } from '../../../context/context.js';\nimport { PersistenceDocumentDb } from '../../interfaces.js';\nimport { IdbService } from '../IdbService.js';\nimport {\n\tcloseDatabase,\n\tgetSizeOfObjectStore,\n\tisAbortError,\n\tisTransactionAborted,\n} from '../util.js';\nimport { getRange } from './ranges.js';\n\nexport class IdbDocumentDb extends IdbService implements PersistenceDocumentDb {\n\tconstructor(\n\t\tdb: IDBDatabase,\n\t\tprivate context: ContextWithoutPersistence,\n\t) {\n\t\tsuper(db, context);\n\t\tthis.addDispose(() => {\n\t\t\tthis.context.log(\n\t\t\t\t'info',\n\t\t\t\t'Closing document database for',\n\t\t\t\tcontext.namespace,\n\t\t\t);\n\t\t\treturn closeDatabase(this.db);\n\t\t});\n\t}\n\n\tclose = async () => {\n\t\tawait this.dispose();\n\t};\n\n\tstats = async (): Promise<\n\t\tRecord<string, { count: number; size: number }>\n\t> => {\n\t\tconst collectionNames = Object.keys(this.context.schema.collections);\n\t\tconst collections: Record<string, { count: number; size: number }> = {};\n\t\tawait Promise.all(\n\t\t\tcollectionNames.map(async (name) => {\n\t\t\t\tconst size = await getSizeOfObjectStore(this.db, name);\n\t\t\t\tcollections[name] = size;\n\t\t\t}),\n\t\t);\n\t\treturn collections;\n\t};\n\n\tfindOneOid = async (opts: {\n\t\tcollection: string;\n\t\tindex?: CollectionFilter;\n\t}): Promise<ObjectIdentifier | null> => {\n\t\tconst result = await this.run<IDBCursorWithValue | null>(\n\t\t\topts.collection,\n\t\t\t(store) => {\n\t\t\t\tconst source = opts.index?.where\n\t\t\t\t\t? store.index(opts.index.where)\n\t\t\t\t\t: store;\n\t\t\t\tconst direction = opts.index?.order === 'desc' ? 'prev' : 'next';\n\t\t\t\tconst range = getRange(\n\t\t\t\t\tthis.context.schema,\n\t\t\t\t\topts.collection,\n\t\t\t\t\topts.index,\n\t\t\t\t);\n\t\t\t\treturn source.openCursor(range, direction);\n\t\t\t},\n\t\t\t{ mode: 'readonly' },\n\t\t);\n\t\tif (result) {\n\t\t\treturn createOid(opts.collection, result.primaryKey.toString());\n\t\t}\n\t\treturn null;\n\t};\n\tfindAllOids = async ({\n\t\tcollection,\n\t\tindex,\n\t\toffset,\n\t\tlimit,\n\t}: {\n\t\tcollection: string;\n\t\tindex?: CollectionFilter;\n\t\tlimit?: number;\n\t\toffset?: number;\n\t}): Promise<{ result: ObjectIdentifier[]; hasNextPage: boolean }> => {\n\t\tconst tx = this.createTransaction([collection], { mode: 'readonly' });\n\t\tif (isTransactionAborted(tx)) {\n\t\t\treturn { result: [], hasNextPage: false };\n\t\t}\n\t\tconst store = tx.objectStore(collection);\n\t\tconst source = index?.where ? store.index(index.where) : store;\n\t\tconst direction = index?.order === 'desc' ? 'prev' : 'next';\n\t\tconst range = getRange(this.context.schema, collection, index);\n\t\tconst request = source.openCursor(range, direction);\n\n\t\tlet hasNextPage = false;\n\t\tconst result = await new Promise<string[]>((resolve, reject) => {\n\t\t\tlet hasDoneOffset = !offset;\n\t\t\tlet visited = 0;\n\t\t\tconst results = new Set<ObjectIdentifier>();\n\n\t\t\trequest.onsuccess = () => {\n\t\t\t\tvisited++;\n\t\t\t\tconst cursor = request.result as IDBCursorWithValue | null;\n\t\t\t\tif (!cursor) {\n\t\t\t\t\tresolve(Array.from(results));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// first offset, if we have one. cursor opens at beginning.\n\t\t\t\tif (offset && !hasDoneOffset) {\n\t\t\t\t\tcursor.advance(offset);\n\t\t\t\t\thasDoneOffset = true;\n\t\t\t\t\t// next iteration we begin adding results.\n\t\t\t\t} else {\n\t\t\t\t\t// add result to set, unless we have reached limit.\n\t\t\t\t\tif (!limit || results.size < limit) {\n\t\t\t\t\t\tresults.add(createOid(collection, cursor.primaryKey.toString()));\n\t\t\t\t\t}\n\t\t\t\t\t// even if we reached limit, we keep going one more to check if there's\n\t\t\t\t\t// a next page.\n\t\t\t\t\tif (limit && visited > limit) {\n\t\t\t\t\t\thasNextPage = true;\n\t\t\t\t\t\t// stop iteration here; we reached limit and we have next page\n\t\t\t\t\t\t// info we need.\n\t\t\t\t\t\tresolve(Array.from(results));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcursor.continue();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\trequest.onerror = () => {\n\t\t\t\tif (request.error?.name === 'InvalidStateError') {\n\t\t\t\t\tthis.context.log(\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t`find query failed with InvalidStateError`,\n\t\t\t\t\t\trequest.error,\n\t\t\t\t\t);\n\t\t\t\t\tresolve([]);\n\t\t\t\t} else if (request.error && isAbortError(request.error)) {\n\t\t\t\t\tresolve([]);\n\t\t\t\t} else {\n\t\t\t\t\treject(request.error);\n\t\t\t\t}\n\t\t\t};\n\t\t});\n\n\t\treturn {\n\t\t\tresult,\n\t\t\thasNextPage,\n\t\t};\n\t};\n\n\tsaveEntities = async (\n\t\tentities: { oid: ObjectIdentifier; getSnapshot: () => any }[],\n\t\toptsAndInfo: { abort?: AbortSignal; collections: string[] },\n\t): Promise<void> => {\n\t\tconst options = {\n\t\t\ttransaction: this.createTransaction(optsAndInfo.collections, {\n\t\t\t\tmode: 'readwrite',\n\t\t\t\tabort: optsAndInfo.abort,\n\t\t\t}),\n\t\t};\n\n\t\tconst results = await Promise.allSettled(\n\t\t\tentities.map(async (e) => {\n\t\t\t\tconst snapshot = e.getSnapshot();\n\t\t\t\ttry {\n\t\t\t\t\tawait this.saveDocument(e.oid, snapshot, options);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthis.context.log(\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t`Error saving document ${e.oid} (${JSON.stringify(snapshot)})`,\n\t\t\t\t\t\terr,\n\t\t\t\t\t);\n\t\t\t\t\tif (err instanceof Error) {\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new Error('Unknown error saving document');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\n\t\tconst failures = results.filter((r) => r.status === 'rejected');\n\t\tif (failures.length) {\n\t\t\t// in the case of a failure to save a document, it doesn't quite make sense to cancel or rollback whatever is\n\t\t\t// currently happening. when restoring imports, etc, this makes the app stuck. if only a few docs failed, maybe\n\t\t\t// there's some data corruption somewhere, but we can just lose those without affecting the rest of the data.\n\t\t\tif (failures.length === results.length) {\n\t\t\t\t// but if ALL of them failed, that's trouble...\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Failed to save any documents. Something must be quite wrong.',\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.context.log(\n\t\t\t\t'error',\n\t\t\t\t'Failed to save documents:',\n\t\t\t\tfailures,\n\t\t\t\t\". See logs above. This only affects querying these documents. Let's hope a future attempt will correct them...\",\n\t\t\t);\n\t\t}\n\n\t\toptions.transaction.commit();\n\t};\n\n\treset = async (): Promise<void> => {\n\t\tconst names = Object.keys(this.context.schema.collections);\n\t\tconst tx = this.createTransaction(names, { mode: 'readwrite' });\n\t\tawait Promise.all(\n\t\t\tnames.map((name) =>\n\t\t\t\tthis.run(name, (store) => store.clear(), { transaction: tx }),\n\t\t\t),\n\t\t);\n\t\tthis.context.entityEvents.emit('collectionsChanged', names);\n\t\tthis.context.log('info', '\uD83D\uDCA8 Reset queryable storage');\n\t};\n\n\tprivate saveDocument = async (\n\t\toid: ObjectIdentifier,\n\t\tdoc: any,\n\t\t{ transaction }: { transaction?: IDBTransaction },\n\t) => {\n\t\tthis.context.log('debug', `Saving document indexes for querying ${oid}`);\n\t\tconst { collection, id } = decomposeOid(oid);\n\t\ttry {\n\t\t\tif (!doc) {\n\t\t\t\tawait this.run(collection, (store) => store.delete(id), {\n\t\t\t\t\tmode: 'readwrite',\n\t\t\t\t\ttransaction,\n\t\t\t\t});\n\t\t\t\tthis.context.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t`Deleted document indexes for querying ${oid}`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst schema = this.context.schema.collections[collection];\n\t\t\t\t// no need to validate before storing; the entity's snapshot is already validated.\n\t\t\t\tconst indexes = getIndexValues(schema, doc);\n\t\t\t\tindexes['@@@snapshot'] = JSON.stringify(doc);\n\t\t\t\tawait this.run(collection, (store) => store.put(indexes), {\n\t\t\t\t\tmode: 'readwrite',\n\t\t\t\t\ttransaction,\n\t\t\t\t});\n\t\t\t\tthis.context.log('debug', `Save complete for ${oid}`, indexes);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthis.context.log('error', `Error saving document ${oid}`, err);\n\t\t\tthrow err;\n\t\t}\n\t};\n}\n", "import { Context } from '../../../../internal.js';\nimport {\n\topenDatabase as baseOpenDatabase,\n\tcloseDatabase,\n\tgetDocumentDbName,\n\tglobalIDB,\n\tstoreRequestPromise,\n} from '../../util.js';\n\n/**\n * Upgrades the database to the given version, using the given upgrader function.\n */\nexport async function upgradeDatabase(\n\tindexedDb: IDBFactory,\n\tnamespace: string,\n\tversion: number,\n\tupgrader: (\n\t\ttransaction: IDBTransaction,\n\t\tdb: IDBDatabase,\n\t\tevent: IDBVersionChangeEvent,\n\t) => void,\n\tlog?: (...args: any[]) => void,\n): Promise<IDBDatabase> {\n\tlog?.('debug', 'Upgrading database', namespace, 'to version', version);\n\tfunction openAndUpgrade(\n\t\tresolve: (db: IDBDatabase) => void,\n\t\treject: (err: Error) => void,\n\t) {\n\t\tconst request = indexedDb.open(getDocumentDbName(namespace), version);\n\t\tlet wasUpgraded = false;\n\t\trequest.onupgradeneeded = (event) => {\n\t\t\tconst transaction = request.transaction!;\n\t\t\tupgrader(transaction, request.result, event);\n\t\t\twasUpgraded = true;\n\t\t};\n\t\trequest.onsuccess = async (event) => {\n\t\t\tif (wasUpgraded) {\n\t\t\t\t// close the database\n\t\t\t\tawait closeDatabase(request.result);\n\t\t\t\tresolve(request.result);\n\t\t\t} else {\n\t\t\t\treject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t'Database was not upgraded when a version change was expected',\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\t\trequest.onerror = (event) => {\n\t\t\treject(request.error || new Error('Unknown error'));\n\t\t};\n\t\trequest.onblocked = (event) => {\n\t\t\tlog?.('Database upgrade blocked!');\n\t\t};\n\t}\n\treturn new Promise<IDBDatabase>(openAndUpgrade);\n}\n\nexport async function openDatabase({\n\tindexedDB = globalIDB,\n\tnamespace,\n\tversion,\n\tlog,\n}: {\n\tindexedDB?: IDBFactory;\n\tnamespace: string;\n\tversion: number;\n\tlog?: Context['log'];\n}): Promise<IDBDatabase> {\n\tif (version <= 0) {\n\t\tthrow new Error('Cannot open database at version less than 1');\n\t}\n\tlog?.('debug', 'Opening database', namespace, 'at version', version);\n\tconst db = await baseOpenDatabase(\n\t\tgetDocumentDbName(namespace),\n\t\tversion,\n\t\tindexedDB,\n\t);\n\tlog?.('debug', 'Database opened', namespace, 'at version', db.version);\n\tif (db.version !== version) {\n\t\tlog?.(\n\t\t\t'warn',\n\t\t\t`Opened database version ${db.version} but expected version ${version} for namespace ${namespace}`,\n\t\t);\n\t}\n\n\tdb.addEventListener('versionchange', (event) => {\n\t\tdb.close();\n\t});\n\n\tdb.addEventListener('close', () => {\n\t\tlog?.('warn', 'Database closed', namespace);\n\t});\n\n\treturn db;\n}\n\nexport async function copyAll(\n\tsourceDatabase: IDBDatabase,\n\ttargetDatabase: IDBDatabase,\n) {\n\t// DOMStringList... doesn't have iterable... why\n\tconst sourceStoreNames = new Array<string>();\n\tfor (let i = 0; i < sourceDatabase.objectStoreNames.length; i++) {\n\t\tsourceStoreNames.push(sourceDatabase.objectStoreNames[i]);\n\t}\n\n\tconst copyFromTransaction = sourceDatabase.transaction(\n\t\tsourceStoreNames,\n\t\t'readonly',\n\t);\n\tconst copyFromStores = sourceStoreNames.map((name) =>\n\t\tcopyFromTransaction.objectStore(name),\n\t);\n\tconst allObjects = await Promise.all(\n\t\tcopyFromStores.map((store) => storeRequestPromise(store.getAll())),\n\t);\n\n\tconst copyToTransaction = targetDatabase.transaction(\n\t\tsourceStoreNames,\n\t\t'readwrite',\n\t);\n\tconst copyToStores = sourceStoreNames.map((name) =>\n\t\tcopyToTransaction.objectStore(name),\n\t);\n\n\tfor (let i = 0; i < copyToStores.length; i++) {\n\t\tawait Promise.all(\n\t\t\tallObjects[i].map((obj) => {\n\t\t\t\treturn storeRequestPromise(copyToStores[i].put(obj));\n\t\t\t}),\n\t\t);\n\t}\n}\n", "import { Migration } from '@verdant-web/common';\nimport { ContextWithoutPersistence } from '../../context/context.js';\nimport {\n\tPersistenceFileDb,\n\tPersistenceImplementation,\n\tPersistenceNamespace,\n} from '../interfaces.js';\nimport { IdbPersistenceFileDb } from './files/IdbPersistenceFileDb.js';\nimport { IdbMetadataDb } from './metadata/IdbMetadataDb.js';\nimport { openMetadataDatabase } from './metadata/openMetadataDatabase.js';\nimport { IdbDocumentDb } from './queries/IdbDocumentDb.js';\nimport { openDatabase, upgradeDatabase } from './queries/migration/db.js';\nimport {\n\tcloseDatabase,\n\tdeleteDatabase,\n\tgetDocumentDbName,\n\tgetMetadataDbName,\n\tgetNamespaceFromDatabaseInfo,\n\toverwriteDatabase,\n} from './util.js';\n\nexport class IdbPersistence implements PersistenceImplementation {\n\tname = 'IdbPersistence';\n\tconstructor(private indexedDB: IDBFactory = window.indexedDB) {}\n\n\tgetNamespaces = async (): Promise<string[]> => {\n\t\t// list all idb database names\n\t\tconst dbs = await this.indexedDB.databases();\n\t\treturn Array.from(\n\t\t\tnew Set<string>(\n\t\t\t\tdbs.map(getNamespaceFromDatabaseInfo).filter((n): n is string => !!n),\n\t\t\t),\n\t\t);\n\t};\n\n\tgetNamespaceVersion = async (namespace: string): Promise<number> => {\n\t\tconst databaseName = getDocumentDbName(namespace);\n\t\tconst dbInfo = await this.indexedDB.databases();\n\t\tconst existingDb = dbInfo.find((info) => info.name === databaseName);\n\t\tif (existingDb) {\n\t\t\treturn existingDb.version ?? 0;\n\t\t}\n\n\t\treturn 0;\n\t};\n\n\tdeleteNamespace = async (namespace: string): Promise<void> => {\n\t\tawait Promise.all([\n\t\t\tdeleteDatabase(getMetadataDbName(namespace), this.indexedDB),\n\t\t\tdeleteDatabase([namespace, 'collections'].join('_'), this.indexedDB),\n\t\t]);\n\t};\n\n\topenNamespace = async (\n\t\tnamespace: string,\n\t): Promise<IdbPersistenceNamespace> => {\n\t\treturn new IdbPersistenceNamespace(this.indexedDB, namespace);\n\t};\n\n\tcopyNamespace = async (\n\t\tfrom: string,\n\t\tto: string,\n\t\tctx: ContextWithoutPersistence,\n\t): Promise<void> => {\n\t\tconst fromCtx = ctx.cloneWithOptions({\n\t\t\tnamespace: from,\n\t\t}) as ContextWithoutPersistence;\n\t\tconst toCtx = ctx.cloneWithOptions({\n\t\t\tnamespace: to,\n\t\t}) as ContextWithoutPersistence;\n\t\tconst { db: fromMetaDb } = await openMetadataDatabase({\n\t\t\tindexedDB: this.indexedDB,\n\t\t\tlog: fromCtx.log,\n\t\t\tnamespace: fromCtx.namespace,\n\t\t});\n\n\t\t// no need to involve files, as they store all data\n\t\t// in the metadata database.\n\n\t\tconst fromDocumentsDb = await openDatabase({\n\t\t\tindexedDB: this.indexedDB,\n\t\t\tnamespace: fromCtx.namespace,\n\t\t\tversion: fromCtx.schema.version,\n\t\t\tlog: fromCtx.log,\n\t\t});\n\n\t\tfromCtx.log(\n\t\t\t'info',\n\t\t\t`Copying data from ${fromCtx.namespace} to ${toCtx.namespace}`,\n\t\t);\n\n\t\tawait overwriteDatabase(\n\t\t\tfromMetaDb,\n\t\t\tgetMetadataDbName(toCtx.namespace),\n\t\t\ttoCtx,\n\t\t\tthis.indexedDB,\n\t\t);\n\t\tawait overwriteDatabase(\n\t\t\tfromDocumentsDb,\n\t\t\tgetDocumentDbName(toCtx.namespace),\n\t\t\ttoCtx,\n\t\t\tthis.indexedDB,\n\t\t);\n\n\t\tawait closeDatabase(fromMetaDb);\n\t\tawait closeDatabase(fromDocumentsDb);\n\t};\n}\n\nclass IdbPersistenceNamespace implements PersistenceNamespace {\n\tconstructor(\n\t\tprivate indexedDB: IDBFactory,\n\t\tprivate namespace: string,\n\t) {}\n\tprivate metadataDb: IDBDatabase | undefined;\n\n\topenFiles(ctx: ContextWithoutPersistence): Promise<PersistenceFileDb> {\n\t\tif (!this.metadataDb) {\n\t\t\tthrow new Error(\n\t\t\t\t'Metadata database must be opened first. This is a bug in Verdant.',\n\t\t\t);\n\t\t}\n\t\treturn Promise.resolve(new IdbPersistenceFileDb(this.metadataDb, ctx));\n\t}\n\n\topenMetadata = async (ctx: ContextWithoutPersistence) => {\n\t\tconst { db } = await openMetadataDatabase({\n\t\t\tindexedDB: this.indexedDB,\n\t\t\tlog: ctx.log,\n\t\t\tnamespace: this.namespace,\n\t\t});\n\t\tthis.metadataDb = db;\n\t\tctx.persistenceShutdownHandler.register(() => closeDatabase(db));\n\t\treturn new IdbMetadataDb(db, ctx);\n\t};\n\n\topenDocuments = async (ctx: ContextWithoutPersistence) => {\n\t\tconst db = await openDatabase({\n\t\t\tversion: ctx.schema.version,\n\t\t\tindexedDB: this.indexedDB,\n\t\t\tlog: ctx.log,\n\t\t\tnamespace: this.namespace,\n\t\t});\n\t\tctx.persistenceShutdownHandler.register(() => closeDatabase(db));\n\t\treturn new IdbDocumentDb(db, ctx);\n\t};\n\n\tapplyMigration = async (\n\t\tctx: ContextWithoutPersistence,\n\t\tmigration: Migration<any>,\n\t): Promise<void> => {\n\t\tctx.log(\n\t\t\t'debug',\n\t\t\t'Applying migration',\n\t\t\tmigration.newSchema.version,\n\t\t\tmigration,\n\t\t);\n\t\tawait upgradeDatabase(\n\t\t\tthis.indexedDB,\n\t\t\tthis.namespace,\n\t\t\tmigration.newSchema.version,\n\t\t\t(transaction, db) => {\n\t\t\t\tfor (const newCollection of migration.addedCollections) {\n\t\t\t\t\tdb.createObjectStore(newCollection, {\n\t\t\t\t\t\tkeyPath: migration.newSchema.collections[newCollection].primaryKey,\n\t\t\t\t\t\tautoIncrement: false,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tfor (const collection of migration.allCollections) {\n\t\t\t\t\tif (!db.objectStoreNames.contains(collection)) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Expected object store for collection ${collection} to exist during migration, but it did not`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconst store = transaction.objectStore(collection);\n\t\t\t\t\t// apply new indexes\n\t\t\t\t\tfor (const newIndex of migration.addedIndexes[collection] || []) {\n\t\t\t\t\t\tstore.createIndex(newIndex.name, newIndex.name, {\n\t\t\t\t\t\t\tmultiEntry: newIndex.multiEntry,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// remove old indexes\n\t\t\t\t\tfor (const oldIndex of migration.removedIndexes[collection] || []) {\n\t\t\t\t\t\tstore.deleteIndex(oldIndex.name);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor (const removedCollection of migration.removedCollections) {\n\t\t\t\t\t// !! can't delete the store, because old operations that relate to\n\t\t\t\t\t// this store may still exist in history. instead, we can clear it out\n\t\t\t\t\t// and leave it in place\n\t\t\t\t\ttransaction.objectStore(removedCollection).clear();\n\t\t\t\t}\n\t\t\t},\n\t\t\tctx.log,\n\t\t);\n\t};\n}\n", "export class ShutdownHandler {\n\tprivate consumed = false;\n\tprivate readonly handlers: (() => Promise<void>)[] = [];\n\tconstructor(\n\t\tprivate log?: (\n\t\t\tlevel: 'debug' | 'info' | 'warn' | 'error' | 'critical',\n\t\t\t...args: any[]\n\t\t) => void,\n\t) {}\n\n\tregister(handler: () => Promise<void>) {\n\t\tthis.handlers.push(handler);\n\t}\n\n\tasync shutdown() {\n\t\tif (this.consumed) {\n\t\t\tthis.log?.('warn', 'ShutdownHandler already consumed');\n\t\t}\n\n\t\tthis.consumed = true;\n\t\tawait Promise.all(this.handlers.map((handler) => handler()));\n\t\tthis.handlers.length = 0;\n\t}\n\n\tget isShuttingDown() {\n\t\treturn this.consumed;\n\t}\n\n\treset = () => {\n\t\tthis.consumed = false;\n\t};\n}\n", "import { hashObject, StorageSchema } from '@verdant-web/common';\n\nexport function getWipNamespace(namespace: string, schema: StorageSchema) {\n\treturn `@@wip-${namespace}-${hashObject(schema)}`;\n}\n", "import {\n\tAuthorizationKey,\n\tCollectionFilter,\n\tMigration,\n\tMigrationEngine,\n\tObjectIdentifier,\n\taddFieldDefaults,\n\tassert,\n\tassignOidsToAllSubObjects,\n\tcloneDeep,\n\tcreateOid,\n\tdiffToPatches,\n\tgetOid,\n\tremoveOidPropertiesFromAllSubObjects,\n} from '@verdant-web/common';\nimport { ContextWithoutPersistence } from '../../context/context.js';\nimport { PersistenceDocumentDb, PersistenceNamespace } from '../interfaces.js';\nimport { PersistenceMetadata } from '../PersistenceMetadata.js';\n\nfunction getMigrationMutations({\n\tmigration,\n\tnewOids,\n\tctx,\n\tmeta,\n}: {\n\tmigration: Migration<any>;\n\tnewOids: string[];\n\tctx: ContextWithoutPersistence;\n\tmeta: PersistenceMetadata;\n}) {\n\treturn migration.allCollections.reduce((acc, collectionName) => {\n\t\tacc[collectionName] = {\n\t\t\tput: async (doc: any, options?: { access?: AuthorizationKey }) => {\n\t\t\t\t// add defaults\n\t\t\t\taddFieldDefaults(migration.newSchema.collections[collectionName], doc);\n\t\t\t\tconst primaryKey =\n\t\t\t\t\tdoc[migration.newSchema.collections[collectionName].primaryKey];\n\t\t\t\tconst oid = createOid(collectionName, primaryKey);\n\t\t\t\tnewOids.push(oid);\n\n\t\t\t\tawait ctx.time.withMigrationTime(migration.version, () =>\n\t\t\t\t\tmeta.insertData({\n\t\t\t\t\t\toperations: ctx.patchCreator.createInitialize(\n\t\t\t\t\t\t\tdoc,\n\t\t\t\t\t\t\toid,\n\t\t\t\t\t\t\toptions?.access,\n\t\t\t\t\t\t),\n\t\t\t\t\t\tisLocal: true,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn doc;\n\t\t\t},\n\t\t\tdelete: async (id: string) => {\n\t\t\t\tconst rootOid = createOid(collectionName, id);\n\t\t\t\tawait ctx.time.withMigrationTime(migration.version, () =>\n\t\t\t\t\tmeta.deleteDocument(rootOid),\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\t\treturn acc;\n\t}, {} as any);\n}\n\nfunction getMigrationQueries({\n\tmigration,\n\tcontext,\n\tdocuments,\n\tmeta,\n}: {\n\tmigration: Migration<any>;\n\tcontext: ContextWithoutPersistence;\n\tdocuments: PersistenceDocumentDb;\n\tmeta: PersistenceMetadata;\n}) {\n\treturn migration.oldCollections.reduce((acc, collectionName) => {\n\t\tacc[collectionName] = {\n\t\t\tget: async (id: string) => {\n\t\t\t\tconst oid = createOid(collectionName, id);\n\t\t\t\tconst doc = await meta.getDocumentSnapshot(oid, {\n\t\t\t\t\t// only get the snapshot up to the previous version (newer operations may have synced)\n\t\t\t\t\tto: context.time.nowWithVersion(migration.oldSchema.version),\n\t\t\t\t});\n\t\t\t\treturn doc;\n\t\t\t},\n\t\t\tfindOne: async (filter: CollectionFilter) => {\n\t\t\t\tconst oid = await documents.findOneOid({\n\t\t\t\t\tcollection: collectionName,\n\t\t\t\t\tindex: filter,\n\t\t\t\t});\n\t\t\t\tif (!oid) return null;\n\t\t\t\tconst doc = await meta.getDocumentSnapshot(oid, {\n\t\t\t\t\t// only get the snapshot up to the previous version (newer operations may have synced)\n\t\t\t\t\tto: context.time.nowWithVersion(migration.oldSchema.version),\n\t\t\t\t});\n\t\t\t\treturn doc;\n\t\t\t},\n\t\t\tfindAll: async (filter: CollectionFilter) => {\n\t\t\t\tconst { result: oids } = await documents.findAllOids({\n\t\t\t\t\tcollection: collectionName,\n\t\t\t\t\tindex: filter,\n\t\t\t\t});\n\t\t\t\tconst docs = await Promise.all(\n\t\t\t\t\toids.map(async (oid) =>\n\t\t\t\t\t\tmeta.getDocumentSnapshot(oid, {\n\t\t\t\t\t\t\t// only get the snapshot up to the previous version (newer operations may have synced)\n\t\t\t\t\t\t\tto: context.time.nowWithVersion(migration.oldSchema.version),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn docs;\n\t\t\t},\n\t\t};\n\t\treturn acc;\n\t}, {} as any);\n}\n\nexport async function getMigrationEngine({\n\tmigration,\n\tcontext,\n\tns,\n\tmeta,\n}: {\n\tlog?: (...args: any[]) => void;\n\tmigration: Migration;\n\tcontext: ContextWithoutPersistence;\n\tns: PersistenceNamespace;\n\tmeta: PersistenceMetadata;\n}): Promise<MigrationEngine> {\n\tconst migrationContext = context.cloneWithOptions({\n\t\tschema: migration.oldSchema,\n\t});\n\tif (migration.oldSchema.version === 0) {\n\t\treturn getInitialMigrationEngine({\n\t\t\tmigration,\n\t\t\tcontext: migrationContext,\n\t\t\tmeta,\n\t\t});\n\t}\n\n\tconst newOids = new Array<ObjectIdentifier>();\n\n\tconst documents = await ns.openDocuments(migrationContext);\n\tconst queries = getMigrationQueries({\n\t\tmigration,\n\t\tcontext: migrationContext,\n\t\tdocuments,\n\t\tmeta,\n\t});\n\tconst mutations = getMigrationMutations({\n\t\tmigration,\n\t\tnewOids,\n\t\tctx: migrationContext,\n\t\tmeta,\n\t});\n\tconst deleteCollection = async (collection: string) => {\n\t\tawait meta.deleteCollection(collection);\n\t};\n\tconst awaitables = new Array<Promise<any>>();\n\tconst engine: MigrationEngine = {\n\t\tlog: context.log,\n\t\tnewOids,\n\t\tdeleteCollection,\n\t\tmigrate: async (collection, strategy) => {\n\t\t\tconst docs = await queries[collection].findAll();\n\t\t\tcontext.log(\n\t\t\t\t'debug',\n\t\t\t\t`Migrating ${docs.length} documents in ${collection}`,\n\t\t\t);\n\n\t\t\tawait Promise.all(\n\t\t\t\tdocs.filter(Boolean).map(async (doc: any) => {\n\t\t\t\t\tconst rootOid = getOid(doc);\n\t\t\t\t\tassert(\n\t\t\t\t\t\t!!rootOid,\n\t\t\t\t\t\t`Document is missing an OID: ${JSON.stringify(doc)}`,\n\t\t\t\t\t);\n\t\t\t\t\t// FIXME: this could be optimized (making n queries for authz\n\t\t\t\t\t// when the snapshots themselves are derived from the same data...)\n\t\t\t\t\t// maybe don't use the findAll query, and instead go a level\n\t\t\t\t\t// lower to retain access to lower level data here?\n\t\t\t\t\tconst authz = await meta.getDocumentAuthz(rootOid);\n\t\t\t\t\tconst original = cloneDeep(doc);\n\t\t\t\t\t// @ts-ignore - excessive type resolution\n\t\t\t\t\tconst newValue = await strategy(doc);\n\t\t\t\t\tif (newValue) {\n\t\t\t\t\t\t// the migration has altered the shape of our document. we need\n\t\t\t\t\t\t// to create the operation from the diff and write it to meta as\n\t\t\t\t\t\t// a migration patch\n\t\t\t\t\t\tremoveOidPropertiesFromAllSubObjects(original);\n\t\t\t\t\t\tremoveOidPropertiesFromAllSubObjects(newValue);\n\t\t\t\t\t\tassignOidsToAllSubObjects(newValue);\n\t\t\t\t\t\tconst patches = diffToPatches(\n\t\t\t\t\t\t\toriginal,\n\t\t\t\t\t\t\tnewValue,\n\t\t\t\t\t\t\t() => context.time.zeroWithVersion(migration.version),\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t[],\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// incoming unknown objects are assumed to be the same\n\t\t\t\t\t\t\t\t// as any pre-existing object.\n\t\t\t\t\t\t\t\tmergeUnknownObjects: true,\n\t\t\t\t\t\t\t\t// if a field is undefined in the new value, it should be\n\t\t\t\t\t\t\t\t// erased. this is the only way to allow users to remove\n\t\t\t\t\t\t\t\t// entries in maps during migrations. it is a little\n\t\t\t\t\t\t\t\t// dangerous for other types, though.\n\t\t\t\t\t\t\t\tdefaultUndefined: false,\n\t\t\t\t\t\t\t\tauthz,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (patches.length > 0) {\n\t\t\t\t\t\t\tawait meta.insertData({\n\t\t\t\t\t\t\t\toperations: patches,\n\t\t\t\t\t\t\t\tisLocal: true,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t\tqueries,\n\t\tmutations,\n\t\tawaitables,\n\t\tclose: async () => {\n\t\t\tawait documents.close();\n\t\t},\n\t};\n\treturn engine;\n}\n\nfunction getInitialMigrationEngine({\n\tmigration,\n\tcontext,\n\tmeta,\n}: {\n\tcontext: ContextWithoutPersistence;\n\tmigration: Migration;\n\tmeta: PersistenceMetadata;\n}): MigrationEngine {\n\tconst newOids = new Array<ObjectIdentifier>();\n\n\tconst queries = new Proxy({} as any, {\n\t\tget() {\n\t\t\tthrow new Error(\n\t\t\t\t'Queries are not available in initial migrations; there is no database yet!',\n\t\t\t);\n\t\t},\n\t}) as any;\n\n\tconst mutations = getMigrationMutations({\n\t\tmigration,\n\t\tnewOids,\n\t\tctx: context,\n\t\tmeta,\n\t});\n\tconst engine: MigrationEngine = {\n\t\tlog: context.log,\n\t\tnewOids,\n\t\tdeleteCollection: () => {\n\t\t\tthrow new Error(\n\t\t\t\t'Calling deleteCollection() in initial migrations is not supported! Use initial migrations to seed initial data using mutations.',\n\t\t\t);\n\t\t},\n\t\tmigrate: () => {\n\t\t\tthrow new Error(\n\t\t\t\t'Calling migrate() in initial migrations is not supported! Use initial migrations to seed initial data using mutations.',\n\t\t\t);\n\t\t},\n\t\tqueries,\n\t\tmutations,\n\t\tawaitables: [],\n\t\tclose: () => Promise.resolve(),\n\t};\n\treturn engine;\n}\n", "import {\n\tdecomposeOid,\n\tgetOidRoot,\n\tMigration,\n\tMigrationEngine,\n} from '@verdant-web/common';\nimport { ContextWithoutPersistence } from '../../context/context.js';\nimport { ClientOperation, PersistenceDocumentDb } from '../interfaces.js';\nimport { PersistenceMetadata } from '../PersistenceMetadata.js';\n\nexport async function finalizeMigration({\n\tctx,\n\tdocuments,\n\tmigration,\n\tmeta,\n\tengine,\n}: {\n\tctx: ContextWithoutPersistence;\n\tdocuments: PersistenceDocumentDb;\n\tmeta: PersistenceMetadata;\n\tmigration: Migration<any>;\n\tengine: MigrationEngine;\n}) {\n\t/**\n\t * In cases where operations from the future have been\n\t * received by this client, we may have created entire\n\t * documents in metadata which were not written to storage\n\t * because all of their operations were in the future (\n\t * i.e. in the next version). We have to find those documents\n\t * and also write their snapshots to storage, because they\n\t * won't be present in storage already to 'refresh,' so\n\t * if we don't analyze metadata for 'future' operations like\n\t * this, we won't know they exist.\n\t *\n\t * This led to behavior where the metadata would be properly\n\t * synced, but after upgrading the app and migrating, items\n\t * would be missing from findAll and findOne queries.\n\t */\n\tconst docsWithUnappliedMigrations = await getDocsWithUnappliedMigrations({\n\t\tcurrentVersion: migration.oldSchema.version,\n\t\tnewVersion: migration.newSchema.version,\n\t\tctx,\n\t\tmeta,\n\t});\n\n\t// once the schema is ready, we can write back the migrated documents\n\n\tfor (const collection of migration.allCollections) {\n\t\t// map the keys to OIDs\n\t\tconst { result: oids } = await documents.findAllOids({\n\t\t\tcollection,\n\t\t});\n\t\toids.push(\n\t\t\t...engine.newOids.filter((oid) => {\n\t\t\t\treturn decomposeOid(oid).collection === collection;\n\t\t\t}),\n\t\t\t...docsWithUnappliedMigrations.filter((oid) => {\n\t\t\t\treturn decomposeOid(oid).collection === collection;\n\t\t\t}),\n\t\t);\n\n\t\tconst snapshots = await Promise.all(\n\t\t\toids.map(async (oid) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst snap = await meta.getDocumentSnapshot(oid);\n\t\t\t\t\treturn [oid, snap];\n\t\t\t\t} catch (e) {\n\t\t\t\t\t// this seems to happen with baselines/ops which are not fully\n\t\t\t\t\t// cleaned up after deletion?\n\t\t\t\t\tctx.log(\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t'Could not regenerate snapshot during migration for oid',\n\t\t\t\t\t\toid,\n\t\t\t\t\t\t'this document will not be preserved',\n\t\t\t\t\t\te,\n\t\t\t\t\t);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\n\t\tconst views: [string, any][] = snapshots.filter(\n\t\t\t(s: any): s is [string, any] => !!s,\n\t\t);\n\n\t\t// now we can write the documents back\n\t\tawait documents.saveEntities(\n\t\t\tviews.map(([oid, snapshot]) => ({\n\t\t\t\toid,\n\t\t\t\tgetSnapshot() {\n\t\t\t\t\treturn snapshot;\n\t\t\t\t},\n\t\t\t})),\n\t\t\t{\n\t\t\t\tcollections: [collection],\n\t\t\t},\n\t\t);\n\t}\n}\n\n/**\n * Gets a list of root OIDs for all documents which had operations stored already\n * that were not applied to their queryable snapshots because they were in the\n * future. These documents need to be refreshed in storage.\n */\nasync function getDocsWithUnappliedMigrations({\n\tcurrentVersion,\n\tnewVersion: _,\n\tctx,\n\tmeta,\n}: {\n\tcurrentVersion: number;\n\tnewVersion: number;\n\tctx: ContextWithoutPersistence;\n\tmeta: PersistenceMetadata;\n}) {\n\t// scan for all operations in metadata after the current version.\n\t// this could be more efficient if also filtering below or equal newVersion but\n\t// that seems so unlikely in practice...\n\tconst unappliedOperations: ClientOperation[] = [];\n\tawait meta.iterateAllOperations(\n\t\t(op) => {\n\t\t\tunappliedOperations.push(op);\n\t\t},\n\t\t{\n\t\t\tfrom: ctx.time.zeroWithVersion(currentVersion + 1),\n\t\t},\n\t);\n\treturn Array.from(\n\t\tnew Set(unappliedOperations.map((op) => getOidRoot(op.oid))),\n\t);\n}\n", "import { Migration, VerdantError } from '@verdant-web/common';\n\nexport function getMigrationPath({\n\tcurrentVersion,\n\ttargetVersion,\n\tmigrations,\n}: {\n\tcurrentVersion: number;\n\ttargetVersion: number;\n\tmigrations: Migration[];\n}) {\n\tconst path = getNextPathStep({\n\t\tcurrentVersion,\n\t\ttargetVersion,\n\t\tmigrations,\n\t});\n\tif (!path) {\n\t\tthrow new VerdantError(\n\t\t\tVerdantError.Code.MigrationPathNotFound,\n\t\t\tundefined,\n\t\t\t`No migration path found from ${currentVersion} to ${targetVersion}! This is a bug. If you're seeing this, contact the developer and provide them with the full contents of this message.`,\n\t\t);\n\t}\n\treturn path;\n}\n\nfunction getNextPathStep({\n\tcurrentVersion,\n\ttargetVersion,\n\tmigrations,\n}: {\n\tcurrentVersion: number;\n\ttargetVersion: number;\n\tmigrations: Migration[];\n}): Migration[] | null {\n\tif (currentVersion === targetVersion) {\n\t\treturn [];\n\t}\n\n\tconst fromHere = migrations\n\t\t.filter((m) => m.oldSchema.version === currentVersion)\n\t\t.sort((a, b) => b.newSchema.version - a.newSchema.version);\n\n\t// keep trying next steps, starting from the largest step,\n\t// until we find one that leads to the target version down the line\n\twhile (fromHere.length > 0) {\n\t\tconst next = fromHere.shift()!;\n\t\t// this one goes too far (probably never relevant, but still)\n\t\tif (next.newSchema.version > targetVersion) {\n\t\t\treturn null;\n\t\t}\n\t\t// exact match - we're done, return the path\n\t\tif (next.newSchema.version === targetVersion) {\n\t\t\treturn [next];\n\t\t}\n\t\t// look ahead a down the line. do we reach the target? if so,\n\t\t// we choose this path.\n\t\tconst nextPath = getNextPathStep({\n\t\t\tcurrentVersion: next.newSchema.version,\n\t\t\ttargetVersion,\n\t\t\tmigrations,\n\t\t});\n\t\tif (nextPath) {\n\t\t\treturn [next, ...nextPath];\n\t\t}\n\n\t\t// otherwise, try the next one with a smaller increment\n\t}\n\n\t// no paths from here match at all! if another layer is calling this one,\n\t// it will fallback to its next longest step. otherwise there may\n\t// be no paths at all...\n\treturn null;\n}\n", "import { Migration } from '@verdant-web/common';\nimport { ContextWithoutPersistence } from '../../context/context.js';\nimport { ShutdownHandler } from '../../context/ShutdownHandler.js';\nimport { PersistenceNamespace } from '../interfaces.js';\nimport { PersistenceMetadata } from '../PersistenceMetadata.js';\nimport { getMigrationEngine } from './engine.js';\nimport { finalizeMigration } from './finalize.js';\nimport { getMigrationPath } from './paths.js';\n\nexport async function migrate({\n\tcontext,\n\tversion,\n\tmeta,\n}: {\n\tcontext: ContextWithoutPersistence;\n\tmeta: PersistenceMetadata;\n\tversion: number;\n}) {\n\tconst ns = await context.persistence.openNamespace(\n\t\tcontext.namespace,\n\t\tcontext,\n\t);\n\tawait acquireLock(context.namespace, async () => {\n\t\tconst currentVersion = await context.persistence.getNamespaceVersion(\n\t\t\tcontext.namespace,\n\t\t);\n\n\t\tcontext.log(\n\t\t\t'debug',\n\t\t\t'Opening index database',\n\t\t\tcontext.namespace,\n\t\t\t'Current database version:',\n\t\t\tcurrentVersion,\n\t\t\t'target version:',\n\t\t\tversion,\n\t\t\tcontext.schema.wip ? '(wip)' : '',\n\t\t);\n\n\t\tconst toRun = getMigrationPath({\n\t\t\tcurrentVersion,\n\t\t\ttargetVersion: version,\n\t\t\tmigrations: context.migrations,\n\t\t});\n\n\t\tif (toRun.length > 0) {\n\t\t\tcontext.log(\n\t\t\t\t'debug',\n\t\t\t\t'Migrations to run:',\n\t\t\t\ttoRun.map((m) => m.version),\n\t\t\t);\n\t\t\tawait runMigrations({ context, ns, toRun, meta });\n\t\t}\n\t});\n}\n\nasync function acquireLock(namespace: string, procedure: () => Promise<void>) {\n\tif (typeof navigator !== 'undefined' && navigator.locks) {\n\t\tawait navigator.locks.request(`verdant_migration_${namespace}`, procedure);\n\t} else {\n\t\t// TODO: is there a fallback?\n\t\tawait procedure();\n\t}\n}\n\nexport async function runMigrations({\n\tcontext,\n\ttoRun,\n\tns,\n\tmeta,\n}: {\n\tcontext: ContextWithoutPersistence;\n\ttoRun: Migration<any>[];\n\tns: PersistenceNamespace;\n\tmeta: PersistenceMetadata;\n}) {\n\t// disable rebasing for the duration of migrations\n\tcontext.pauseRebasing = true;\n\t// now the fun part\n\tfor (const migration of toRun) {\n\t\tcontext.log(\n\t\t\t'info',\n\t\t\t`\uD83D\uDE80 Running migration v${migration.oldSchema.version} -> v${migration.newSchema.version}`,\n\t\t);\n\t\tconst migrationContext = context.cloneWithOptions({\n\t\t\tschema: migration.oldSchema,\n\t\t\tpersistenceShutdownHandler: new ShutdownHandler(context.log),\n\t\t});\n\t\t// this will only write to our metadata store via operations!\n\t\tconst engine = await getMigrationEngine({\n\t\t\tmigration,\n\t\t\tcontext: migrationContext,\n\t\t\tns,\n\t\t\tmeta,\n\t\t});\n\t\ttry {\n\t\t\tcontext.log(\n\t\t\t\t'debug',\n\t\t\t\t'Migrating data',\n\t\t\t\tmigrationContext.namespace,\n\t\t\t\t'from version',\n\t\t\t\tmigration.oldSchema.version,\n\t\t\t\t'to version',\n\t\t\t\tmigration.newSchema.version,\n\t\t\t);\n\t\t\tawait migration.migrate(engine);\n\t\t\tcontext.log('debug', 'Awaiting remaining migration tasks');\n\t\t\t// wait on any out-of-band async operations to complete\n\t\t\tawait Promise.all(engine.awaitables);\n\t\t} catch (err) {\n\t\t\tcontext.log(\n\t\t\t\t'critical',\n\t\t\t\t`Migration failed (${migration.oldSchema.version} -> ${migration.newSchema.version})`,\n\t\t\t\terr,\n\t\t\t);\n\t\t\tif (err instanceof Error) {\n\t\t\t\tthrow err;\n\t\t\t} else {\n\t\t\t\tthrow new Error('Unknown error during migration');\n\t\t\t}\n\t\t}\n\n\t\tawait engine.close();\n\n\t\tmigrationContext.log(\n\t\t\t'debug',\n\t\t\t'Upgrading database',\n\t\t\tmigrationContext.namespace,\n\t\t\t'from version',\n\t\t\tmigrationContext.schema.version,\n\t\t\t'to version',\n\t\t\tmigration.newSchema.version,\n\t\t);\n\n\t\tawait ns.applyMigration(migrationContext, migration);\n\n\t\t// switch to the new schema\n\t\tmigrationContext.schema = migration.newSchema;\n\t\tconst upgradedDocuments = await ns.openDocuments(migrationContext);\n\n\t\tawait finalizeMigration({\n\t\t\tctx: migrationContext,\n\t\t\tmigration,\n\t\t\tengine,\n\t\t\tdocuments: upgradedDocuments,\n\t\t\tmeta,\n\t\t});\n\t\tawait upgradedDocuments.close();\n\n\t\tmigrationContext.log(\n\t\t\t'debug',\n\t\t\t`Migration of ${migrationContext.namespace} complete.`,\n\t\t);\n\t\tmigrationContext.log(\n\t\t\t'info',\n\t\t\t`\n\t\t\t\t\u2B06\uFE0F v${migration.newSchema.version} Migration complete. Here's the rundown:\n\t\t\t\t\t- Added collections: ${migration.addedCollections.join(', ')}\n\t\t\t\t\t- Removed collections: ${migration.removedCollections.join(', ')}\n\t\t\t\t\t- Changed collections: ${migration.changedCollections.join(', ')}\n\t\t\t\t\t- New indexes: ${Object.keys(migration.addedIndexes)\n\t\t\t\t\t\t.map((col) =>\n\t\t\t\t\t\t\tmigration.addedIndexes[col].map((i) => `${col}.${i.name}`),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.flatMap((i) => i)\n\t\t\t\t\t\t.join(', ')}\n\t\t\t\t\t- Removed indexes: ${Object.keys(migration.removedIndexes)\n\t\t\t\t\t\t.map((col) =>\n\t\t\t\t\t\t\tmigration.removedIndexes[col].map((i) => `${col}.${i.name}`),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.flatMap((i) => i)\n\t\t\t\t\t\t.join(', ')}\n\t\t\t`,\n\t\t);\n\t}\n\tcontext.pauseRebasing = false;\n}\n", "import { FileData, FileRef } from '@verdant-web/common';\nimport { Context, FileConfig } from '../context/context.js';\nimport { PersistedFileData, PersistenceFileDb } from './interfaces.js';\n\nexport class PersistenceFiles {\n\tconstructor(\n\t\tprivate db: PersistenceFileDb,\n\t\tprivate context: Omit<Context, 'queries'>,\n\t) {\n\t\tcontext.internalEvents.subscribe('filesDeleted', this.onFileRefsDeleted);\n\t\t// on startup, try deleting old files.\n\t\tthis.cleanupDeletedFiles();\n\t}\n\n\tprivate get config(): Required<FileConfig> {\n\t\treturn {\n\t\t\tcanCleanupDeletedFile(fileData) {\n\t\t\t\treturn (\n\t\t\t\t\tfileData.deletedAt !== null &&\n\t\t\t\t\tfileData.deletedAt < Date.now() - 1000 * 60 * 24 * 3\n\t\t\t\t);\n\t\t\t},\n\t\t\t...this.context.config.files,\n\t\t};\n\t}\n\n\tonServerReset = (since: string | null) =>\n\t\tthis.db.resetSyncedStatusSince(since);\n\t/**\n\t * Adds a file to persistence.\n\t * Optionally download and re-upload remote files to create a new copy.\n\t */\n\tadd = async (file: FileData, options?: { cloneRemote?: boolean }) => {\n\t\t// this method accepts a FileData which refers to a remote\n\t\t// file, as well as local files. in the case of a remote file,\n\t\t// we actually re-download and upload the file again. this powers\n\t\t// the cloning of documents with files; we clone their filedata\n\t\t// and re-upload to a new file ID. otherwise, when the cloned\n\t\t// filedata was marked deleted, the original file would be deleted\n\t\t// and the clone would refer to a missing file.\n\t\tif (file.url && !(file.localPath || file.file) && options?.cloneRemote) {\n\t\t\tthis.context.log(\n\t\t\t\t'debug',\n\t\t\t\t'Cloning remote file added to a new entity. Downloading remote file...',\n\t\t\t\tfile.id,\n\t\t\t);\n\t\t\tconst blob = await this.loadFileContents(file, 0, 3);\n\t\t\t// convert blob to file with name and type\n\t\t\tfile.file = new File([blob], file.name, { type: file.type });\n\t\t\t// remove the URL - it points to the original file's uploaded server version,\n\t\t\t// but this file is a clone\n\t\t\tdelete file.url;\n\t\t\tthis.context.log(\n\t\t\t\t'debug',\n\t\t\t\t'Downloaded remote file',\n\t\t\t\tfile.id,\n\t\t\t\tfile.name,\n\t\t\t\t'. Cleared its remote URL.',\n\t\t\t);\n\t\t} else if (!file.url && !file.file && !file.localPath) {\n\t\t\tthis.context.log(\n\t\t\t\t'warn',\n\t\t\t\t'File added without a file or URL. This file will not be available for use.',\n\t\t\t\tfile.id,\n\t\t\t);\n\t\t}\n\n\t\t// always reset remote status to false, this is a new file just created\n\t\t// and must be uploaded, even if it is cloned from an uploaded file.\n\t\tfile.remote = false;\n\n\t\t// store in persistence db\n\t\tthis.context.log('debug', 'Adding file to persistence', file);\n\t\tawait this.db.add(file);\n\t\t// fire event for sync to pick up and upload the file\n\t\tthis.context.internalEvents.emit('fileAdded', file);\n\t\tthis.context.globalEvents.emit('fileSaved', file);\n\t\tthis.context.log(\n\t\t\t'debug',\n\t\t\t'File added',\n\t\t\tfile.id,\n\t\t\tfile.name,\n\t\t\tfile.type,\n\t\t\tfile.file\n\t\t\t\t? 'with binary file'\n\t\t\t\t: file.url\n\t\t\t\t\t? 'with url'\n\t\t\t\t\t: file.localPath\n\t\t\t\t\t\t? 'with local path'\n\t\t\t\t\t\t: 'with no data',\n\t\t);\n\t\treturn file;\n\t};\n\tupdate = async (file: FileData) => {\n\t\tawait this.db.add(file);\n\t\tthis.context.globalEvents.emit('fileSaved', file);\n\t\tthis.context.log('debug', 'File updated', file.id, file.name);\n\t};\n\tonUploaded = this.db.markUploaded.bind(this.db);\n\tget = this.db.get.bind(this.db);\n\tgetAll = this.db.getAll.bind(this.db);\n\tlistUnsynced = this.db.listUnsynced.bind(this.db);\n\titerateOverPendingDelete = this.db.iterateOverPendingDelete.bind(this.db);\n\tstats = this.db.stats.bind(this.db);\n\n\tprivate getFileExportName = (originalFileName: string, id: string) => {\n\t\treturn `${id}___${originalFileName}`;\n\t};\n\texport = async (downloadRemote = true) => {\n\t\tconst storedFiles = await this.getAll();\n\t\tif (downloadRemote) {\n\t\t\tfor (const storedFile of storedFiles) {\n\t\t\t\t// if it doesn't have a buffer, we need to read one from the server\n\t\t\t\tif (!storedFile.file && (storedFile.url || storedFile.localPath)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst blob = await this.loadFileContents(storedFile);\n\t\t\t\t\t\tstoredFile.file = blob;\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tthis.context.log(\n\t\t\t\t\t\t\t'error',\n\t\t\t\t\t\t\t\"Failed to download file to cache it locally. The file will still be available using its URL. Check the file server's CORS configuration.\",\n\t\t\t\t\t\t\tstoredFile,\n\t\t\t\t\t\t\terr,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else if (!storedFile.file) {\n\t\t\t\t\tthis.context.log(\n\t\t\t\t\t\t'warn',\n\t\t\t\t\t\t`File ${storedFile.id} has no file or URL. It will be missing in the export.`,\n\t\t\t\t\t\tstoredFile,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// split files into data and files\n\t\tconst fileData: Array<Omit<PersistedFileData, 'file'>> = [];\n\t\tconst files: Array<File> = [];\n\n\t\tfor (const fileExport of storedFiles) {\n\t\t\tconst file = fileExport.file;\n\t\t\tdelete fileExport.file;\n\t\t\tfileData.push(fileExport);\n\t\t\tif (file) {\n\t\t\t\t// rename with ID\n\t\t\t\tconst asFile = new File(\n\t\t\t\t\t[file],\n\t\t\t\t\tthis.getFileExportName(fileExport.name, fileExport.id),\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: fileExport.type,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tfiles.push(asFile);\n\t\t\t} else {\n\t\t\t\tthis.context.log(\n\t\t\t\t\t'warn',\n\t\t\t\t\t`File ${fileExport.id} was could not be loaded locally or from the server. It will be missing in the export.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tfileData,\n\t\t\tfiles,\n\t\t};\n\t};\n\n\timport = async ({\n\t\tfileData,\n\t\tfiles,\n\t}: {\n\t\tfileData: Array<Omit<PersistedFileData, 'file'>>;\n\t\tfiles: File[];\n\t}) => {\n\t\t// re-attach files to their file data and import\n\t\tconst fileToIdMap = new Map(\n\t\t\tfiles.map((file) => {\n\t\t\t\tconst { id } = this.parseFileExportname(file.name);\n\t\t\t\treturn [id, file];\n\t\t\t}),\n\t\t);\n\t\tconst importedFiles: PersistedFileData[] = fileData.map((fileData) => {\n\t\t\tconst file = fileToIdMap.get(fileData.id);\n\n\t\t\tif (!file) {\n\t\t\t\tthis.context.log('warn', `File ${fileData.id} was not found in import`);\n\t\t\t\treturn fileData;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\t...fileData,\n\t\t\t\tfile,\n\t\t\t};\n\t\t});\n\t\tawait Promise.all(importedFiles.map((file) => this.add(file)));\n\t};\n\n\tprivate parseFileExportname = (name: string) => {\n\t\tconst [id, originalFileName] = name.split('___');\n\t\treturn { id, originalFileName };\n\t};\n\n\tprivate loadFileContents = async (\n\t\tfile: FileData,\n\t\tretries = 0,\n\t\tmaxRetries = 0,\n\t) => {\n\t\ttry {\n\t\t\treturn await this.db.loadFileContents(file, this.context);\n\t\t} catch (err) {\n\t\t\tif (retries < maxRetries) {\n\t\t\t\treturn new Promise<Blob>((resolve, reject) => {\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis.loadFileContents(file, retries + 1, maxRetries).then(\n\t\t\t\t\t\t\tresolve,\n\t\t\t\t\t\t\treject,\n\t\t\t\t\t\t);\n\t\t\t\t\t}, 1000);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.context.log(\n\t\t\t\t\t'error',\n\t\t\t\t\t`Failed to download file after ${maxRetries} retries`,\n\t\t\t\t\terr,\n\t\t\t\t);\n\t\t\t\tthrow new Error(`Failed to download file after ${maxRetries} retries`, {\n\t\t\t\t\tcause: err,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\n\tcleanupDeletedFiles = async () => {\n\t\tlet count = 0;\n\t\tlet skipCount = 0;\n\t\tconst deletable: string[] = [];\n\t\tawait this.iterateOverPendingDelete((fileData) => {\n\t\t\tif (this.config.canCleanupDeletedFile(fileData)) {\n\t\t\t\tcount++;\n\t\t\t\tdeletable.push(fileData.id);\n\t\t\t} else {\n\t\t\t\tskipCount++;\n\t\t\t}\n\t\t});\n\t\tfor (const id of deletable) {\n\t\t\tawait this.db.delete(id);\n\t\t}\n\n\t\tthis.context.log(\n\t\t\t'info',\n\t\t\t`Cleaned up ${count} files, skipped ${skipCount} files`,\n\t\t);\n\t};\n\n\tprivate onFileRefsDeleted = async (fileRefs: FileRef[]) => {\n\t\tawait Promise.all(\n\t\t\tfileRefs.map(async (fileRef) => {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.db.markPendingDelete(fileRef.id);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthis.context.log('error', 'Failed to mark file for deletion', err);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t\tthis.context.log(\n\t\t\t'info',\n\t\t\t`Marked ${fileRefs.length} files as pending delete`,\n\t\t);\n\t};\n}\n", "import {\n\tapplyPatch,\n\tassert,\n\tassignOid,\n\tDocumentBaseline,\n\tgetOidRoot,\n\tObjectIdentifier,\n\tOperation,\n\tsubstituteRefsWithObjects,\n} from '@verdant-web/common';\nimport cuid from 'cuid';\nimport { ContextWithoutPersistence } from '../context/context.js';\nimport {\n\tAbstractTransaction,\n\tClientOperation,\n\tCommonQueryOptions,\n\tLocalReplicaInfo,\n\tMetadataExport,\n\tPersistenceMetadataDb,\n} from './interfaces.js';\nimport { MessageCreator } from './MessageCreator.js';\nimport { PersistenceRebaser } from './PersistenceRebaser.js';\n\nexport class PersistenceMetadata {\n\tprivate rebaser: PersistenceRebaser;\n\t/** Available to others, like sync... */\n\treadonly messageCreator: MessageCreator;\n\n\tconstructor(\n\t\tprivate db: PersistenceMetadataDb,\n\t\tprivate ctx: ContextWithoutPersistence,\n\t) {\n\t\tthis.rebaser = new PersistenceRebaser(db, this, ctx);\n\t\tthis.messageCreator = new MessageCreator(db, this, ctx);\n\t}\n\n\tprivate insertOperations = async (\n\t\toperations: ClientOperation[],\n\t\toptions?: { transaction?: AbstractTransaction },\n\t) => {\n\t\tthis.ctx.log(\n\t\t\t'debug',\n\t\t\t`Inserting ${operations.length} operations`,\n\t\t\toperations,\n\t\t);\n\n\t\tconst affectedDocumentOids = await this.db.addOperations(\n\t\t\toperations,\n\t\t\toptions,\n\t\t);\n\n\t\tfor (const op of operations) {\n\t\t\tthis.ctx.globalEvents.emit('operation', op);\n\t\t}\n\n\t\t// we can now enqueue and check for rebase opportunities\n\t\tif (\n\t\t\t!this.ctx.config.persistence?.disableRebasing &&\n\t\t\t!this.ctx.pauseRebasing\n\t\t) {\n\t\t\tthis.rebaser.tryAutonomousRebase();\n\t\t}\n\n\t\treturn affectedDocumentOids;\n\t};\n\n\tprivate insertLocalOperations = async (\n\t\toperations: Operation[],\n\t\toptions?: { transaction?: AbstractTransaction },\n\t) => {\n\t\tif (operations.length === 0) return;\n\n\t\t// add local flag, in place.\n\t\tfor (const operation of operations) {\n\t\t\t(operation as ClientOperation).isLocal = true;\n\t\t}\n\t\tawait this.insertOperations(operations as ClientOperation[], options);\n\t\tthis.ctx.log(\n\t\t\t'debug',\n\t\t\t`Inserted ${operations.length} local operations; sending sync message`,\n\t\t);\n\t\tconst message = await this.messageCreator.createOperation({ operations });\n\t\tthis.ctx.internalEvents.emit('outgoingSyncMessage', message);\n\t};\n\n\tprivate insertRemoteOperations = async (\n\t\toperations: Operation[],\n\t\toptions?: { transaction?: AbstractTransaction },\n\t) => {\n\t\tif (operations.length === 0) return [];\n\n\t\t// add local flag, in place\n\t\tfor (const operation of operations) {\n\t\t\t(operation as ClientOperation).isLocal = false;\n\t\t}\n\n\t\tawait this.insertOperations(operations as ClientOperation[], options);\n\n\t\tthis.ack(operations[operations.length - 1].timestamp);\n\t};\n\n\tprivate insertRemoteBaselines = async (\n\t\tbaselines: DocumentBaseline[],\n\t\toptions?: { transaction?: AbstractTransaction },\n\t) => {\n\t\tif (baselines.length === 0) return [];\n\t\tthis.ctx.log('debug', `Inserting ${baselines.length} remote baselines`);\n\n\t\tawait this.db.setBaselines(baselines, options);\n\n\t\t// this.ack(baselines[baselines.length - 1].timestamp);\n\n\t\tconst affectedOidSet = new Set<ObjectIdentifier>();\n\t\tbaselines.forEach((baseline) => {\n\t\t\taffectedOidSet.add(getOidRoot(baseline.oid));\n\t\t});\n\n\t\treturn Array.from(affectedOidSet);\n\t};\n\n\tdeleteDocument = async (rootOid: string) => {\n\t\tconst oids = new Set<ObjectIdentifier>();\n\t\tconst documentOid = getOidRoot(rootOid);\n\t\tassert(documentOid === rootOid, 'Must be root document OID');\n\t\toids.add(documentOid);\n\t\t// readwrite mode to block on other write transactions\n\t\treturn this.db.transaction(\n\t\t\t{\n\t\t\t\tstoreNames: ['baselines', 'operations'],\n\t\t\t},\n\t\t\tasync (transaction) => {\n\t\t\t\tawait Promise.all([\n\t\t\t\t\tthis.db.iterateDocumentBaselines(\n\t\t\t\t\t\tdocumentOid,\n\t\t\t\t\t\t(baseline) => {\n\t\t\t\t\t\t\toids.add(baseline.oid);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ transaction },\n\t\t\t\t\t),\n\t\t\t\t\tthis.db.iterateDocumentOperations(\n\t\t\t\t\t\tdocumentOid,\n\t\t\t\t\t\t(patch) => {\n\t\t\t\t\t\t\toids.add(patch.oid);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ transaction },\n\t\t\t\t\t),\n\t\t\t\t]);\n\t\t\t\tconst authz = await this.getDocumentAuthz(documentOid);\n\t\t\t\tconst ops = new Array<Operation>();\n\t\t\t\tfor (const oid of oids) {\n\t\t\t\t\tops.push({\n\t\t\t\t\t\toid,\n\t\t\t\t\t\ttimestamp: this.ctx.time.now,\n\t\t\t\t\t\tdata: { op: 'delete' },\n\t\t\t\t\t\tauthz,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this.insertLocalOperations(ops, { transaction });\n\t\t\t},\n\t\t);\n\t};\n\n\tdeleteCollection = async (collection: string) => {\n\t\tconst oids = new Set<ObjectIdentifier>();\n\t\treturn this.db.transaction(\n\t\t\t{\n\t\t\t\tstoreNames: ['baselines', 'operations'],\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t\tasync (transaction) => {\n\t\t\t\tawait Promise.all([\n\t\t\t\t\tthis.db.iterateCollectionBaselines(\n\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t(baseline) => {\n\t\t\t\t\t\t\toids.add(baseline.oid);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ transaction },\n\t\t\t\t\t),\n\t\t\t\t\tthis.db.iterateCollectionOperations(\n\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t(patch) => {\n\t\t\t\t\t\t\toids.add(patch.oid);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ transaction },\n\t\t\t\t\t),\n\t\t\t\t]);\n\n\t\t\t\tconst ops = new Array<Operation>();\n\t\t\t\tfor (const oid of oids) {\n\t\t\t\t\tops.push({\n\t\t\t\t\t\toid,\n\t\t\t\t\t\ttimestamp: this.ctx.time.now,\n\t\t\t\t\t\tdata: { op: 'delete' },\n\t\t\t\t\t\tauthz: undefined,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn this.insertLocalOperations(ops, { transaction });\n\t\t\t},\n\t\t);\n\t};\n\n\tgetDocumentSnapshot = async (\n\t\toid: ObjectIdentifier,\n\t\toptions: { to?: string } = {},\n\t) => {\n\t\tconst documentOid = getOidRoot(oid);\n\t\tassert(documentOid === oid, 'Must be root document OID');\n\t\treturn this.db.transaction(\n\t\t\t{\n\t\t\t\tstoreNames: ['baselines', 'operations'],\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t\tasync (transaction) => {\n\t\t\t\tconst baselines: DocumentBaseline[] = [];\n\t\t\t\tawait this.db.iterateDocumentBaselines(\n\t\t\t\t\tdocumentOid,\n\t\t\t\t\t(b) => {\n\t\t\t\t\t\tbaselines.push(b);\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttransaction,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tconst objectMap = new Map<ObjectIdentifier, any>();\n\t\t\t\tfor (const baseline of baselines) {\n\t\t\t\t\tif (baseline.snapshot) {\n\t\t\t\t\t\tassignOid(baseline.snapshot, baseline.oid);\n\t\t\t\t\t}\n\t\t\t\t\tobjectMap.set(baseline.oid, baseline.snapshot);\n\t\t\t\t}\n\t\t\t\tawait this.db.iterateDocumentOperations(\n\t\t\t\t\tdocumentOid,\n\t\t\t\t\t(op) => {\n\t\t\t\t\t\tconst obj = objectMap.get(op.oid) || undefined;\n\t\t\t\t\t\tconst newObj = applyPatch(obj, op.data);\n\t\t\t\t\t\tif (newObj) {\n\t\t\t\t\t\t\tassignOid(newObj, op.oid);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tobjectMap.set(op.oid, newObj);\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttransaction,\n\t\t\t\t\t\t// only apply operations up to the current time\n\t\t\t\t\t\tto: options.to || this.ctx.time.now,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tconst root = objectMap.get(documentOid);\n\t\t\t\tif (root) {\n\t\t\t\t\tsubstituteRefsWithObjects(root, objectMap);\n\t\t\t\t}\n\t\t\t\treturn root;\n\t\t\t},\n\t\t);\n\t};\n\n\tgetDocumentData = async (\n\t\toid: ObjectIdentifier,\n\t\toptions?: { abort?: AbortSignal },\n\t) => {\n\t\treturn this.db.transaction(\n\t\t\t{\n\t\t\t\tstoreNames: ['baselines', 'operations'],\n\t\t\t\tabort: options?.abort,\n\t\t\t},\n\t\t\tasync (transaction) => {\n\t\t\t\tconst baselines: DocumentBaseline[] = [];\n\t\t\t\tconst operations: Record<ObjectIdentifier, Operation[]> = {};\n\t\t\t\tawait Promise.all([\n\t\t\t\t\tthis.db.iterateDocumentBaselines(\n\t\t\t\t\t\toid,\n\t\t\t\t\t\t(baseline) => {\n\t\t\t\t\t\t\tbaselines.push(baseline);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttransaction,\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t\tthis.db.iterateDocumentOperations(\n\t\t\t\t\t\toid,\n\t\t\t\t\t\t(op) => {\n\t\t\t\t\t\t\toperations[op.oid] ??= [];\n\t\t\t\t\t\t\toperations[op.oid].push(op);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ transaction },\n\t\t\t\t\t),\n\t\t\t\t]);\n\t\t\t\treturn {\n\t\t\t\t\tbaselines,\n\t\t\t\t\toperations,\n\t\t\t\t};\n\t\t\t},\n\t\t);\n\t};\n\n\tgetDocumentAuthz = async (oid: ObjectIdentifier) => {\n\t\tlet authz;\n\t\tawait this.db.iterateEntityOperations(oid, (op) => {\n\t\t\tif (op.data.op === 'initialize') {\n\t\t\t\tauthz = op.authz;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t});\n\t\treturn authz;\n\t};\n\n\tinsertData = async (\n\t\tdata: {\n\t\t\tbaselines?: DocumentBaseline[];\n\t\t\toperations?: Operation[];\n\t\t\tisLocal?: boolean;\n\t\t},\n\t\toptions?: { abort?: AbortSignal },\n\t) => {\n\t\treturn this.db.transaction(\n\t\t\t{\n\t\t\t\tstoreNames: ['baselines', 'operations'],\n\t\t\t\tabort: options?.abort,\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t\tasync (transaction) => {\n\t\t\t\tthis.ctx.log('debug', 'Begin insert data transaction');\n\t\t\t\tif (data.baselines) {\n\t\t\t\t\tawait this.insertRemoteBaselines(data.baselines, { transaction });\n\t\t\t\t}\n\t\t\t\tthis.ctx.log('debug', 'Inserted baselines (if any)');\n\t\t\t\tif (options?.abort?.aborted) throw new Error('Aborted');\n\t\t\t\tif (data.operations) {\n\t\t\t\t\tif (data.isLocal) {\n\t\t\t\t\t\tthis.ctx.log('debug', 'Inserting local operations');\n\t\t\t\t\t\tawait this.insertLocalOperations(data.operations, { transaction });\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.ctx.log('debug', 'Inserting remote operations');\n\t\t\t\t\t\tawait this.insertRemoteOperations(data.operations, { transaction });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.ctx.log('debug', 'End insert data transaction');\n\t\t\t},\n\t\t);\n\t};\n\n\tupdateLastSynced = async (timestamp: string) => {\n\t\tif (this.ctx.closing) return;\n\n\t\treturn this.updateLocalReplica({\n\t\t\tlastSyncedLogicalTime: timestamp,\n\t\t});\n\t};\n\tsetGlobalAck = async (ack: string) => {\n\t\tif (this.ctx.closing) return;\n\t\tawait this.db.setGlobalAck(ack);\n\t\tif (!this.ctx.config.persistence?.disableRebasing) {\n\t\t\tawait this.rebaser.scheduleRebase(ack);\n\t\t}\n\t};\n\n\t// caching local replica as it's accessed often and only changed\n\t// via this class.\n\tprivate _cachedLocalReplica: LocalReplicaInfo | null = null;\n\tprivate _creatingLocalReplica: Promise<LocalReplicaInfo> | undefined =\n\t\tundefined;\n\tgetLocalReplica = async (\n\t\toptions?: CommonQueryOptions,\n\t): Promise<LocalReplicaInfo> => {\n\t\tif (this._cachedLocalReplica) return this._cachedLocalReplica;\n\n\t\tconst lookup = await this.db.getLocalReplica(options);\n\t\tif (lookup) {\n\t\t\tthis.ctx.log('debug', 'Read local replica', lookup);\n\t\t\tthis._cachedLocalReplica = lookup;\n\t\t\treturn lookup;\n\t\t}\n\n\t\tif (this._creatingLocalReplica) {\n\t\t\treturn this._creatingLocalReplica;\n\t\t}\n\n\t\tthis._creatingLocalReplica = (async () => {\n\t\t\tconst replicaId = cuid();\n\t\t\tconst replicaInfo: LocalReplicaInfo = {\n\t\t\t\tid: replicaId,\n\t\t\t\tuserId: null,\n\t\t\t\tackedLogicalTime: null,\n\t\t\t\tlastSyncedLogicalTime: null,\n\t\t\t};\n\t\t\tawait this.db.updateLocalReplica(replicaInfo);\n\t\t\tthis._cachedLocalReplica = replicaInfo;\n\t\t\treturn replicaInfo;\n\t\t})();\n\t\treturn this._creatingLocalReplica;\n\t};\n\tupdateLocalReplica = async (\n\t\tdata: Partial<LocalReplicaInfo>,\n\t\topts?: { transaction?: AbstractTransaction },\n\t) => {\n\t\tconst original = await this.getLocalReplica(opts);\n\t\tassert(!!original, 'Local replica must exist');\n\t\tObject.assign(original, data);\n\t\tthis._cachedLocalReplica = original;\n\t\tawait this.db.updateLocalReplica(original, opts);\n\t};\n\n\t// used to construct sync messages\n\titerateLocalOperations = this.db.iterateLocalOperations;\n\titerateAllOperations = this.db.iterateAllOperations;\n\titerateAllBaselines = this.db.iterateAllBaselines;\n\n\treset = async () => {\n\t\tif (this.ctx.closing) return;\n\t\tawait this.db.reset();\n\t};\n\tstats = this.db.stats;\n\n\texport = async (): Promise<MetadataExport> => {\n\t\tconst baselines = new Array<DocumentBaseline>();\n\t\tconst operations = new Array<ClientOperation>();\n\t\treturn this.db.transaction(\n\t\t\t{\n\t\t\t\tstoreNames: ['baselines', 'operations'],\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t\tasync (transaction) => {\n\t\t\t\tawait this.iterateAllOperations(\n\t\t\t\t\t(op) => {\n\t\t\t\t\t\toperations.push(op);\n\t\t\t\t\t},\n\t\t\t\t\t{ transaction },\n\t\t\t\t);\n\t\t\t\tawait this.iterateAllBaselines(\n\t\t\t\t\t(baseline) => {\n\t\t\t\t\t\tbaselines.push(baseline);\n\t\t\t\t\t},\n\t\t\t\t\t{ transaction },\n\t\t\t\t);\n\t\t\t\tconst localReplica = await this.getLocalReplica();\n\t\t\t\treturn {\n\t\t\t\t\toperations,\n\t\t\t\t\tbaselines,\n\t\t\t\t\tlocalReplica,\n\t\t\t\t\tschemaVersion: this.ctx.schema.version,\n\t\t\t\t};\n\t\t\t},\n\t\t);\n\t};\n\n\tresetFrom = async (data: MetadataExport) => {\n\t\tthis._cachedLocalReplica = null;\n\n\t\t// await this.db.transaction(\n\t\t// \t{ mode: 'readwrite', storeNames: ['baselines', 'operations', 'info'] },\n\t\t// \tasync (tx) => {\n\t\t// \t\tawait this.db.reset({ clearReplica: true, transaction: tx });\n\n\t\t// \t\tif (data.localReplica) {\n\t\t// \t\t\tawait this.updateLocalReplica(\n\t\t// \t\t\t\t{\n\t\t// \t\t\t\t\tackedLogicalTime: data.localReplica.ackedLogicalTime,\n\t\t// \t\t\t\t\tlastSyncedLogicalTime: data.localReplica.lastSyncedLogicalTime,\n\t\t// \t\t\t\t},\n\t\t// \t\t\t\t{\n\t\t// \t\t\t\t\ttransaction: tx,\n\t\t// \t\t\t\t},\n\t\t// \t\t\t);\n\t\t// \t\t}\n\t\t// \t},\n\t\t// );\n\n\t\t// transaction wasn't working for IDB (invalid state -- it was closing early?)\n\t\tawait this.db.reset({ clearReplica: true });\n\n\t\tif (data.localReplica) {\n\t\t\tawait this.updateLocalReplica({\n\t\t\t\tackedLogicalTime: data.localReplica.ackedLogicalTime,\n\t\t\t\tlastSyncedLogicalTime: data.localReplica.lastSyncedLogicalTime,\n\t\t\t});\n\t\t}\n\t\t// after transaction completes, insert new data.\n\t\t// TODO: does this have to be split up like this?\n\t\tthis.ctx.log('debug', 'Resetting metadata from export', data);\n\t\tawait this.insertData({\n\t\t\toperations: data.operations,\n\t\t\tbaselines: data.baselines,\n\t\t\tisLocal: true,\n\t\t});\n\t};\n\n\tmanualRebase = async () => {\n\t\tif (this.ctx.closing || this.ctx.config.persistence?.disableRebasing)\n\t\t\treturn;\n\t\tconst ackInfo = await this.db.getAckInfo();\n\t\tif (ackInfo.globalAckTimestamp) {\n\t\t\tawait this.rebaser.scheduleRebase(ackInfo.globalAckTimestamp);\n\t\t}\n\t};\n\n\tprivate ack = async (timestamp: string) => {\n\t\tconst localReplicaInfo = await this.getLocalReplica();\n\t\t// can't ack timestamps from the future.\n\t\tif (timestamp > this.ctx.time.now) return;\n\n\t\tthis.ctx.internalEvents.emit('outgoingSyncMessage', {\n\t\t\ttype: 'ack',\n\t\t\treplicaId: localReplicaInfo.id,\n\t\t\ttimestamp,\n\t\t});\n\n\t\tif (\n\t\t\t!this.ctx.closing &&\n\t\t\t(!localReplicaInfo.ackedLogicalTime ||\n\t\t\t\ttimestamp > localReplicaInfo.ackedLogicalTime)\n\t\t) {\n\t\t\tthis.updateLocalReplica({ ackedLogicalTime: timestamp });\n\t\t}\n\t};\n}\n", "import {\n\tAckMessage,\n\tDisconnectingMessage,\n\tDocumentBaseline,\n\tgetOidRoot,\n\tHeartbeatMessage,\n\tObjectIdentifier,\n\tOperation,\n\tOperationMessage,\n\tpickValidOperationKeys,\n\tPresenceUpdateMessage,\n\tSyncMessage,\n\tVerdantInternalPresence,\n} from '@verdant-web/common';\n\nimport { Context } from '../context/context.js';\nimport { PersistenceMetadataDb } from './interfaces.js';\nimport type { PersistenceMetadata } from './PersistenceMetadata.js';\n\nexport class MessageCreator {\n\tconstructor(\n\t\tprivate db: PersistenceMetadataDb,\n\t\tprivate meta: PersistenceMetadata,\n\t\tprivate ctx: Pick<Context, 'time' | 'schema' | 'log'>,\n\t) {}\n\n\tcreateOperation = async (\n\t\tinit: Pick<OperationMessage, 'operations'> & {\n\t\t\ttimestamp?: string;\n\t\t},\n\t): Promise<OperationMessage> => {\n\t\tconst localInfo = await this.meta.getLocalReplica();\n\t\tthis.ctx.log('debug', 'Creating operation message', init.operations.length);\n\t\treturn {\n\t\t\ttype: 'op',\n\t\t\ttimestamp: this.ctx.time.now,\n\t\t\treplicaId: localInfo.id,\n\t\t\toperations: init.operations.map(pickValidOperationKeys),\n\t\t};\n\t};\n\n\t/**\n\t * @param since - override local understanding of last sync time\n\t */\n\tcreateSyncStep1 = async (since?: string | null): Promise<SyncMessage> => {\n\t\tconst localReplicaInfo = await this.meta.getLocalReplica();\n\n\t\tconst provideChangesSince =\n\t\t\tsince === null ? null : localReplicaInfo.lastSyncedLogicalTime;\n\n\t\t// collect all of our operations that are newer than the server's last operation\n\t\t// if server replica isn't stored, we're syncing for the first time.\n\t\tconst operations: Operation[] = [];\n\t\tconst affectedDocs = new Set<ObjectIdentifier>();\n\n\t\treturn this.db.transaction(\n\t\t\t{\n\t\t\t\tmode: 'readwrite',\n\t\t\t\tstoreNames: ['operations', 'baselines'],\n\t\t\t},\n\t\t\tasync (tx) => {\n\t\t\t\t// FIXME: this branch gives bad vibes. should we always\n\t\t\t\t// send all operations from other replicas too? is there\n\t\t\t\t// ever a case where we have a \"since\" timestamp and there\n\t\t\t\t// are foreign ops that match it?\n\t\t\t\tif (provideChangesSince) {\n\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t'debug',\n\t\t\t\t\t\t'Syncing local operations since',\n\t\t\t\t\t\tprovideChangesSince,\n\t\t\t\t\t);\n\t\t\t\t\tawait this.db.iterateLocalOperations(\n\t\t\t\t\t\t(patch) => {\n\t\t\t\t\t\t\toperations.push(pickValidOperationKeys(patch));\n\t\t\t\t\t\t\taffectedDocs.add(getOidRoot(patch.oid));\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tafter: provideChangesSince,\n\t\t\t\t\t\t\t// block on writes to prevent race conditions\n\t\t\t\t\t\t\ttransaction: tx,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthis.ctx.log('debug', 'Syncing all operations');\n\t\t\t\t\t// if providing the whole history, don't limit to only local\n\t\t\t\t\t// operations\n\t\t\t\t\tawait this.db.iterateAllOperations(\n\t\t\t\t\t\t(patch) => {\n\t\t\t\t\t\t\toperations.push(pickValidOperationKeys(patch));\n\t\t\t\t\t\t\taffectedDocs.add(getOidRoot(patch.oid));\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttransaction: tx,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// we only need to send baselines if we've never synced before\n\t\t\t\tlet baselines: DocumentBaseline[] = [];\n\t\t\t\tif (!provideChangesSince) {\n\t\t\t\t\tawait this.db.iterateAllBaselines(\n\t\t\t\t\t\t(b) => {\n\t\t\t\t\t\t\tbaselines.push(b);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttransaction: tx,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (operations.length > 0) {\n\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t'debug',\n\t\t\t\t\t\t`Syncing ${operations.length} operations since ${provideChangesSince}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'sync',\n\t\t\t\t\tschemaVersion: this.ctx.schema.version,\n\t\t\t\t\ttimestamp: this.ctx.time.now,\n\t\t\t\t\treplicaId: localReplicaInfo.id,\n\t\t\t\t\tresyncAll: !localReplicaInfo.lastSyncedLogicalTime,\n\t\t\t\t\toperations,\n\t\t\t\t\tbaselines,\n\t\t\t\t\tsince: provideChangesSince,\n\t\t\t\t};\n\t\t\t},\n\t\t);\n\t};\n\n\tcreatePresenceUpdate = async (data: {\n\t\tpresence?: any;\n\t\tinternal?: VerdantInternalPresence;\n\t}): Promise<PresenceUpdateMessage> => {\n\t\tconst localReplicaInfo = await this.meta.getLocalReplica();\n\t\treturn {\n\t\t\ttype: 'presence-update',\n\t\t\tpresence: data.presence,\n\t\t\treplicaId: localReplicaInfo.id,\n\t\t\tinternal: data.internal,\n\t\t};\n\t};\n\n\tcreateHeartbeat = async (): Promise<HeartbeatMessage> => {\n\t\treturn {\n\t\t\ttype: 'heartbeat',\n\t\t};\n\t};\n\n\tcreateAck = async (nonce: string): Promise<AckMessage> => {\n\t\tconst localReplicaInfo = await this.meta.getLocalReplica();\n\t\treturn {\n\t\t\ttype: 'ack',\n\t\t\ttimestamp: this.ctx.time.now,\n\t\t\treplicaId: localReplicaInfo.id,\n\t\t\tnonce,\n\t\t};\n\t};\n\n\tcreateDisconnecting = async (\n\t\treason: string,\n\t): Promise<DisconnectingMessage> => {\n\t\tconst localReplicaInfo = await this.meta.getLocalReplica();\n\t\treturn {\n\t\t\ttype: 'disconnecting',\n\t\t\treplicaId: localReplicaInfo.id,\n\t\t\treason,\n\t\t};\n\t};\n}\n", "import {\n\tapplyPatch,\n\tassignOid,\n\tisFileRef,\n\tObjectIdentifier,\n\tRef,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { AbstractTransaction, PersistenceMetadataDb } from './interfaces.js';\nimport type { PersistenceMetadata } from './PersistenceMetadata.js';\n\nexport class PersistenceRebaser {\n\tconstructor(\n\t\tprivate db: PersistenceMetadataDb,\n\t\tprivate meta: PersistenceMetadata,\n\t\tprivate ctx: Pick<\n\t\t\tContext,\n\t\t\t| 'closing'\n\t\t\t| 'log'\n\t\t\t| 'time'\n\t\t\t| 'internalEvents'\n\t\t\t| 'globalEvents'\n\t\t\t| 'config'\n\t\t\t| 'closeLock'\n\t\t\t| 'persistenceShutdownHandler'\n\t\t>,\n\t) {}\n\n\t/**\n\t * Autonomous rebases are only allowed for clients who have never synced. They\n\t * keep storage clean for non-syncing clients by compressing history.\n\t */\n\ttryAutonomousRebase = async () => {\n\t\tconst localReplicaInfo = await this.meta.getLocalReplica();\n\t\tif (localReplicaInfo.lastSyncedLogicalTime) return; // cannot autonomously rebase if we've synced\n\t\tif (this.ctx.closing || this.ctx.persistenceShutdownHandler.isShuttingDown)\n\t\t\treturn;\n\t\t// but if we have never synced... we can rebase everything!\n\t\tthis.ctx.log('debug', 'Running autonomous library rebase');\n\t\tawait this.runRebase(this.ctx.time.now);\n\t};\n\n\t/**\n\t * Attempt to autonomously rebase local documents without server intervention.\n\t * This can currently only happen for a client who has never synced before.\n\t * The goal is to allow local-only clients to compress their history to exactly\n\t * their undo stack.\n\t */\n\tprivate runRebase = async (globalAckTimestamp: string) => {\n\t\tif (this.ctx.closing || this.ctx.persistenceShutdownHandler.isShuttingDown)\n\t\t\treturn;\n\n\t\tawait this.db.transaction(\n\t\t\t{\n\t\t\t\tstoreNames: ['baselines', 'operations'],\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t\tasync (transaction) => {\n\t\t\t\t// find all operations before the global ack\n\t\t\t\tconst toRebase = new Set<ObjectIdentifier>();\n\t\t\t\tlet lastTimestamp;\n\t\t\t\tlet operationCount = 0;\n\t\t\t\tawait this.db.iterateAllOperations(\n\t\t\t\t\t(patch) => {\n\t\t\t\t\t\ttoRebase.add(patch.oid);\n\t\t\t\t\t\tlastTimestamp = patch.timestamp;\n\t\t\t\t\t\toperationCount++;\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tbefore: globalAckTimestamp,\n\t\t\t\t\t\ttransaction,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (!toRebase.size) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tthis.ctx.closing ||\n\t\t\t\t\tthis.ctx.persistenceShutdownHandler.isShuttingDown\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// rebase each affected document\n\t\t\t\tlet newBaselines = [];\n\t\t\t\tfor (const oid of toRebase) {\n\t\t\t\t\tnewBaselines.push(\n\t\t\t\t\t\tawait this.rebase(\n\t\t\t\t\t\t\toid,\n\t\t\t\t\t\t\tlastTimestamp || globalAckTimestamp,\n\t\t\t\t\t\t\ttransaction,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t\tthis.ctx.globalEvents.emit('rebase');\n\t};\n\n\t/**\n\t * Debounces rebase attempts to avoid thrashing the database with\n\t * rebase operations.\n\t */\n\tscheduleRebase = async (timestamp: string) => {\n\t\tif (this.rebaseTimeout) {\n\t\t\tclearTimeout(this.rebaseTimeout);\n\t\t}\n\t\tthis.rebaseTimeout = setTimeout(\n\t\t\tthis.runRebase,\n\t\t\tthis.ctx.config.persistence?.rebaseTimeout ?? 10000,\n\t\t\ttimestamp,\n\t\t);\n\t\tthis.ctx.log('debug', 'Scheduled rebase up to global ack', timestamp);\n\t};\n\tprivate rebaseTimeout: NodeJS.Timeout | null = null;\n\n\tprivate rebase = async (\n\t\toid: ObjectIdentifier,\n\t\tupTo: string,\n\t\ttransaction: AbstractTransaction,\n\t) => {\n\t\tif (this.ctx.closing || this.ctx.persistenceShutdownHandler.isShuttingDown)\n\t\t\treturn;\n\n\t\tconst baseline = await this.db.getBaseline(oid, { transaction });\n\t\tlet current: any = baseline?.snapshot || undefined;\n\t\tlet operationsApplied = 0;\n\t\tlet authz = baseline?.authz;\n\t\tconst deletedRefs: Ref[] = [];\n\n\t\tif (this.ctx.closing || this.ctx.persistenceShutdownHandler.isShuttingDown)\n\t\t\treturn;\n\n\t\tawait this.db.iterateEntityOperations(\n\t\t\toid,\n\t\t\t(patch) => {\n\t\t\t\t// FIXME: this seems like the wrong place to do this\n\t\t\t\t// but it's here as a safety measure...\n\t\t\t\tif (!baseline || patch.timestamp > baseline.timestamp) {\n\t\t\t\t\tcurrent = applyPatch(current, patch.data, deletedRefs);\n\t\t\t\t\tif (patch.data.op === 'initialize') {\n\t\t\t\t\t\tauthz = patch.authz;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// delete all prior operations to the baseline\n\t\t\t\toperationsApplied++;\n\t\t\t},\n\t\t\t{\n\t\t\t\tto: upTo,\n\t\t\t\ttransaction,\n\t\t\t},\n\t\t);\n\t\tif (current) {\n\t\t\tassignOid(current, oid);\n\t\t}\n\t\tconst newBaseline = {\n\t\t\toid,\n\t\t\tsnapshot: current,\n\t\t\ttimestamp: upTo,\n\t\t\tauthz,\n\t\t};\n\n\t\t// still time to cancel now...\n\t\tif (this.ctx.closing || this.ctx.persistenceShutdownHandler.isShuttingDown)\n\t\t\treturn;\n\n\t\t// FROM HERE, WE ARE COMMITTED TO THE REBASE -- otherwise data will be corrupted.\n\t\tthis.ctx.closeLock = (async () => {\n\t\t\tif (newBaseline.snapshot) {\n\t\t\t\tawait this.db.setBaselines([newBaseline], { transaction });\n\t\t\t} else {\n\t\t\t\tawait this.db.deleteBaseline(oid, { transaction });\n\t\t\t}\n\n\t\t\tawait this.db.deleteEntityOperations(oid, {\n\t\t\t\tto: upTo,\n\t\t\t\ttransaction,\n\t\t\t});\n\n\t\t\tthis.ctx.log(\n\t\t\t\t'debug',\n\t\t\t\t'rebased',\n\t\t\t\toid,\n\t\t\t\t'up to',\n\t\t\t\tupTo,\n\t\t\t\t':',\n\t\t\t\tcurrent,\n\t\t\t\t'and deleted',\n\t\t\t\toperationsApplied,\n\t\t\t\t'operations',\n\t\t\t);\n\n\t\t\t// cleanup deleted refs\n\t\t\tif (deletedRefs.length) {\n\t\t\t\tconst fileRefs = deletedRefs.filter(isFileRef);\n\t\t\t\tif (fileRefs.length) {\n\t\t\t\t\tthis.ctx.internalEvents.emit('filesDeleted', fileRefs);\n\t\t\t\t}\n\t\t\t}\n\t\t})();\n\n\t\treturn newBaseline;\n\t};\n}\n", "import { PersistenceDocumentDb } from './interfaces.js';\nimport { Context } from '../context/context.js';\nimport { decomposeOid, ObjectIdentifier } from '@verdant-web/common';\n\nexport class PersistenceDocuments {\n\tconstructor(\n\t\tprivate db: PersistenceDocumentDb,\n\t\tprivate ctx: Omit<Context, 'queries'>,\n\t) {}\n\n\treset = this.db.reset.bind(this.db);\n\n\tclose = this.db.close.bind(this.db);\n\n\tsaveEntities = async (\n\t\tentities: { oid: ObjectIdentifier; getSnapshot: () => any }[],\n\t\toptions?: { abort?: AbortSignal },\n\t) => {\n\t\tif (entities.length === 0) return;\n\n\t\t// filter entities to remove collections which don't\n\t\t// exist in the schema anymore\n\t\tconst currentCollectionSet = new Set(\n\t\t\tObject.keys(this.ctx.schema.collections),\n\t\t);\n\t\tconst collections: string[] = [];\n\t\tconst filteredEntities = entities.filter((entity) => {\n\t\t\tconst { collection } = decomposeOid(entity.oid);\n\t\t\tif (!currentCollectionSet.has(collection)) {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'warn',\n\t\t\t\t\t`Entity ${entity.oid} is in a collection that no longer exists in the schema. It will not be saved.`,\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!collections.includes(collection)) collections.push(collection);\n\t\t\treturn true;\n\t\t});\n\n\t\tif (collections.length === 0) return;\n\n\t\tthis.ctx.log('debug', 'Saving', filteredEntities.length, 'entities');\n\t\tawait this.db.saveEntities(filteredEntities, {\n\t\t\tabort: options?.abort,\n\t\t\tcollections,\n\t\t});\n\t\tthis.ctx.log('debug', 'Saved', filteredEntities.length, 'entities');\n\t\tthis.ctx.entityEvents.emit('collectionsChanged', collections);\n\t\tfor (const entity of entities) {\n\t\t\tthis.ctx.entityEvents.emit('documentChanged', entity.oid);\n\t\t}\n\t};\n\n\tfindOneOid = this.db.findOneOid.bind(this.db);\n\tfindAllOids = this.db.findAllOids.bind(this.db);\n\n\tstats = this.db.stats.bind(this.db);\n}\n", "import { getOidRoot, VerdantError } from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { ShutdownHandler } from '../context/ShutdownHandler.js';\nimport { getWipNamespace } from '../utils/wip.js';\nimport { ExportedData } from './interfaces.js';\nimport { migrate } from './migration/migrate.js';\nimport { PersistenceFiles } from './PersistenceFiles.js';\nimport { PersistenceMetadata } from './PersistenceMetadata.js';\nimport { PersistenceDocuments } from './PersistenceQueries.js';\n\nexport async function initializePersistence(ctx: Context) {\n\tconst initialSchema = ctx.schema;\n\tif (ctx.schema.wip) {\n\t\t// this is a WIP database, so we need to create a new namespace for the WIP data.\n\t\tctx.namespace = getWipNamespace(ctx.originalNamespace, ctx.schema);\n\t\tctx.log('info', '\uD83D\uDD28', 'Switched to WIP namespace', ctx.namespace);\n\t\t// check if this WIP database is already in use\n\t\tconst namespaces = await ctx.persistence.getNamespaces();\n\n\t\tif (!namespaces.includes(ctx.namespace)) {\n\t\t\t// copy all data to WIP namespace -- from the current version of local\n\t\t\t// data, not the WIP schema version. this may not be n-1, we might\n\t\t\t// be loading a WIP schema over older data.\n\t\t\tconst currentVersion = await ctx.persistence.getNamespaceVersion(\n\t\t\t\tctx.originalNamespace,\n\t\t\t);\n\n\t\t\tif (currentVersion === 0) {\n\t\t\t\t// there is no existing data. nothing to copy.\n\t\t\t\tctx.log('debug', 'No existing data to copy to WIP namespace');\n\t\t\t} else {\n\t\t\t\tconst currentSchema = ctx.oldSchemas?.find(\n\t\t\t\t\t(s) => s.version === currentVersion,\n\t\t\t\t);\n\t\t\t\tif (!currentSchema) {\n\t\t\t\t\tthrow new VerdantError(\n\t\t\t\t\t\tVerdantError.Code.MigrationPathNotFound,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t`Trying to open WIP database for version ${ctx.schema.version}, but the current local data is version ${currentVersion} and a historical schema for that version is not available.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tctx.log(\n\t\t\t\t\t'info',\n\t\t\t\t\t`Copying data from ${ctx.originalNamespace} to ${ctx.namespace}`,\n\t\t\t\t);\n\t\t\t\tawait ctx.persistence.copyNamespace(\n\t\t\t\t\tctx.originalNamespace,\n\t\t\t\t\tctx.namespace,\n\t\t\t\t\t// needs to be the original schema; the copy should be of the original\n\t\t\t\t\t// data and schema structure; the WIP schema migration application happens\n\t\t\t\t\t// below.\n\t\t\t\t\tctx.cloneWithOptions({\n\t\t\t\t\t\tschema: currentSchema,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst namespace = await ctx.persistence.openNamespace(ctx.namespace, ctx);\n\n\tctx.log('info', 'Opening persistence metadata', ctx.namespace);\n\tconst meta = new PersistenceMetadata(await namespace.openMetadata(ctx), ctx);\n\n\tctx.log('info', 'Opening persistence files', ctx.namespace);\n\tconst files = new PersistenceFiles(await namespace.openFiles(ctx), ctx);\n\n\tctx.log('info', 'Migrating document database');\n\tawait migrate({\n\t\tcontext: ctx,\n\t\tversion: ctx.schema.version,\n\t\tmeta,\n\t});\n\n\tctx.log('info', 'Opening persistence documents');\n\tif (ctx.schema.version <= 0) {\n\t\t// debugging....\n\t\tif (ctx.schema !== initialSchema) {\n\t\t\tctx.log(\n\t\t\t\t'critical',\n\t\t\t\t'Schema at initialization does not match original schema. This is likely a bug in Verdant!',\n\t\t\t);\n\t\t\tthrow new VerdantError(\n\t\t\t\tVerdantError.Code.ConfigurationError,\n\t\t\t\tundefined,\n\t\t\t\t`Schema at initialization does not match original schema. This is likely a bug in Verdant!`,\n\t\t\t);\n\t\t}\n\t\tthrow new VerdantError(\n\t\t\tVerdantError.Code.ConfigurationError,\n\t\t\tundefined,\n\t\t\t`Schema version must be greater than 0. Found version ${ctx.schema.version} with collections [${Object.keys(ctx.schema.collections).join(', ')}]\\n${JSON.stringify(ctx.schema)}`,\n\t\t);\n\t}\n\tconst documents = new PersistenceDocuments(\n\t\tawait namespace.openDocuments(ctx),\n\t\tctx,\n\t);\n\n\tif (!ctx.schema.wip) {\n\t\tconst namespaces = await ctx.persistence.getNamespaces();\n\t\t// cleanup old WIP databases\n\t\tfor (const namespace of namespaces) {\n\t\t\tif (namespace.startsWith(`@@wip_`)) {\n\t\t\t\tctx.log('debug', 'Cleaning up old WIP namespace', namespace);\n\t\t\t\tawait ctx.persistence.deleteNamespace(namespace, ctx);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { meta, files, documents };\n}\n\nexport async function importPersistence(\n\tctx: Context,\n\texportedData: ExportedData,\n): Promise<void> {\n\tctx.log('info', 'Importing data from export');\n\t// open persistence at the version of the import\n\tconst exportedSchema = ctx.oldSchemas?.find(\n\t\t(s) => s.version === exportedData.data.schemaVersion,\n\t);\n\tif (!exportedSchema) {\n\t\t// this means the user hasn't upgraded their CLI/client to include old schemas, or\n\t\t// this exported data comes from a version which has since been shortcut.\n\t\tthrow new Error(\n\t\t\t`Could not find schema for version ${exportedData.data.schemaVersion}`,\n\t\t);\n\t}\n\n\t// using a new namespace to put all of this into a temporary zone\n\tconst importedNamespace = `@@import_${Date.now()}`;\n\n\tconst importedContext = ctx.cloneWithOptions({\n\t\tschema: exportedSchema,\n\t\tnamespace: importedNamespace,\n\t\tdisableRebasing: true,\n\t\tpersistenceShutdownHandler: new ShutdownHandler(ctx.log),\n\t});\n\tawait importedContext.reinitialize();\n\tconst importedMeta = await importedContext.meta;\n\n\t// load imported data into persistence\n\tawait importedMeta.resetFrom(exportedData.data);\n\t// need to write indexes here!\n\tconst affectedOids = new Set<string>();\n\tfor (const baseline of exportedData.data.baselines) {\n\t\taffectedOids.add(getOidRoot(baseline.oid));\n\t}\n\tfor (const operation of exportedData.data.operations) {\n\t\taffectedOids.add(getOidRoot(operation.oid));\n\t}\n\tconst toSave = await Promise.all(\n\t\tArray.from(affectedOids).map(async (oid) => {\n\t\t\tconst snapshot = await importedMeta.getDocumentSnapshot(oid);\n\t\t\treturn {\n\t\t\t\toid,\n\t\t\t\tgetSnapshot: () => snapshot,\n\t\t\t};\n\t\t}),\n\t);\n\tawait (await importedContext.documents).saveEntities(toSave);\n\tawait (await importedContext.files).import(exportedData);\n\n\tctx.log('debug', 'Imported data into temporary namespace', importedNamespace);\n\n\t// shut down the imported databases\n\tawait importedContext.persistenceShutdownHandler.shutdown();\n\n\tif (exportedSchema.version !== ctx.schema.version) {\n\t\t// an upgrade of the imported data is needed ; it's an older version\n\t\t// of the schema.\n\n\t\t// upgrade the imported data to the latest schema by re-initializing\n\t\t// a context at the latest version, pointing at the imported namespace\n\t\tconst upgradedContext = importedContext.cloneWithOptions({\n\t\t\tpersistenceShutdownHandler: new ShutdownHandler(ctx.log),\n\t\t\tschema: ctx.schema,\n\t\t\toldSchemas: ctx.oldSchemas,\n\t\t});\n\t\tawait upgradedContext.reinitialize();\n\n\t\tctx.log('debug', 'Upgraded imported data to current schema');\n\n\t\tawait upgradedContext.persistenceShutdownHandler.shutdown();\n\n\t\tctx.log('debug', 'Shut down upgraded databases');\n\t}\n\n\t// shut down the persistence layer\n\tawait ctx.persistenceShutdownHandler.shutdown();\n\n\t// copy the imported data into the current namespace\n\tawait ctx.persistence.copyNamespace(importedNamespace, ctx.namespace, ctx);\n\tctx.log('debug', 'Copied imported data to primary namespace');\n\n\t// restart the persistence layer\n\tawait ctx.reinitialize();\n\tctx.log('debug', 'Reinitialized primary persistence layer');\n\n\t// verify integrity -- this can only be done if imported data was same\n\t// version as current schema, because migrations could add or remove\n\t// operations. still, it's a good sanity check.\n\tif (exportedData.data.schemaVersion === ctx.schema.version) {\n\t\tconst stats = await (await ctx.meta).stats();\n\t\tif (stats.operationsSize.count !== exportedData.data.operations.length) {\n\t\t\tctx.log(\n\t\t\t\t'critical',\n\t\t\t\t'Imported operations count mismatch',\n\t\t\t\t'expected',\n\t\t\t\texportedData.data.operations.length,\n\t\t\t\t'actual',\n\t\t\t\tstats.operationsSize.count,\n\t\t\t);\n\t\t\tthrow new VerdantError(\n\t\t\t\tVerdantError.Code.ImportFailed,\n\t\t\t\tundefined,\n\t\t\t\t'Imported operations count mismatch',\n\t\t\t);\n\t\t}\n\t\tif (stats.baselinesSize.count !== exportedData.data.baselines.length) {\n\t\t\tctx.log(\n\t\t\t\t'critical',\n\t\t\t\t'Imported documents count mismatch',\n\t\t\t\t'expected',\n\t\t\t\texportedData.data.baselines.length,\n\t\t\t\t'actual',\n\t\t\t\tstats.baselinesSize.count,\n\t\t\t);\n\t\t\tthrow new VerdantError(\n\t\t\t\tVerdantError.Code.ImportFailed,\n\t\t\t\tundefined,\n\t\t\t\t'Imported documents count mismatch',\n\t\t\t);\n\t\t}\n\t} else {\n\t\tctx.log(\n\t\t\t'debug',\n\t\t\t'Skipping integrity check due to schema version mismatch (not an error)',\n\t\t\t{\n\t\t\t\texportedVersion: exportedData.data.schemaVersion,\n\t\t\t\tcurrentVersion: ctx.schema.version,\n\t\t\t},\n\t\t);\n\t}\n\n\tctx.log('debug', 'Data copied to primary namespace');\n\n\t// cleanup the imported namespace\n\tawait ctx.persistence.deleteNamespace(importedNamespace, ctx);\n\n\tctx.log('debug', 'Deleted temporary namespace');\n\n\tctx.internalEvents.emit('persistenceReset');\n\tctx.log('info', 'Data imported successfully');\n\n\t// reset to allow future shutdowns.\n\tctx.persistenceShutdownHandler.reset();\n}\n", "import { TimestampProvider } from '@verdant-web/common';\n\nexport class Time {\n\tprivate overrideNow?: () => string;\n\tconstructor(\n\t\tprivate base: TimestampProvider,\n\t\tprivate version: number,\n\t) {}\n\n\tget now() {\n\t\treturn this.overrideNow ? this.overrideNow() : this.base.now(this.version);\n\t}\n\n\twithMigrationTime = async (version: number, run: () => void) => {\n\t\tthis.overrideNow = () => {\n\t\t\treturn this.base.zero(version);\n\t\t};\n\t\trun();\n\t\tthis.overrideNow = undefined;\n\t};\n\n\tupdate = this.base.update.bind(this.base);\n\n\tnowWithVersion = (version: number) => {\n\t\treturn this.base.now(version);\n\t};\n\n\tget zero() {\n\t\treturn this.base.zero(this.version);\n\t}\n\n\tzeroWithVersion = (version: number) => {\n\t\treturn this.base.zero(version);\n\t};\n}\n", "import {\n\tClientMessage,\n\tEventSubscriber,\n\tFileData,\n\tFileRef,\n\tHybridLogicalClockTimestampProvider,\n\tMigration,\n\tObjectIdentifier,\n\tOperation,\n\tPatchCreator,\n\tStorageSchema,\n\tVerdantError,\n} from '@verdant-web/common';\nimport { FakeWeakRef } from '../FakeWeakRef.js';\nimport { UndoHistory } from '../UndoHistory.js';\nimport type { Client } from '../client/Client.js';\nimport { debugLogger, noLogger, VerdantLogger } from '../logger.js';\nimport { PersistenceFiles } from '../persistence/PersistenceFiles.js';\nimport type { PersistenceMetadata } from '../persistence/PersistenceMetadata.js';\nimport type { PersistenceDocuments } from '../persistence/PersistenceQueries.js';\nimport { IdbPersistence } from '../persistence/idb/idbPersistence.js';\nimport {\n\tPersistedFileData,\n\tPersistenceImplementation,\n} from '../persistence/interfaces.js';\nimport { initializePersistence } from '../persistence/persistence.js';\nimport { ServerSyncOptions } from '../sync/Sync.js';\nimport { ShutdownHandler } from './ShutdownHandler.js';\nimport { Time } from './Time.js';\n\nexport interface ContextEnvironment {\n\tWebSocket: typeof WebSocket;\n\tfetch: typeof fetch;\n\tindexedDB: typeof indexedDB;\n\tlocation: Location;\n\thistory: History;\n}\n\nexport const defaultBrowserEnvironment: ContextEnvironment = {\n\tWebSocket: typeof WebSocket !== 'undefined' ? WebSocket : (undefined as any),\n\tfetch: typeof window !== 'undefined' ? window.fetch.bind(window) : fetch!,\n\tindexedDB: typeof indexedDB !== 'undefined' ? indexedDB : (undefined as any),\n\tlocation:\n\t\ttypeof window !== 'undefined' ? window.location : (undefined as any),\n\thistory: typeof window !== 'undefined' ? window.history : (undefined as any),\n};\n\nexport interface ContextInit {\n\t/** The schema used to create this client */\n\tschema: StorageSchema<any>;\n\toldSchemas: StorageSchema<any>[];\n\t/** Migrations, in order, to upgrade to each successive version of the schema */\n\tmigrations: Migration<any>[];\n\t/** Provide a sync config to turn on synchronization with a server */\n\tsync?: ServerSyncOptions;\n\t/**\n\t * Namespaces are used to separate data from different clients in IndexedDB.\n\t */\n\tnamespace: string;\n\t/**\n\t * Provide your own UndoHistory to have a unified undo system across multiple\n\t * clients if you so desire.\n\t */\n\tundoHistory?: UndoHistory;\n\t/**\n\t * Provide a log function to log internal debug messages\n\t */\n\tlog?: VerdantLogger | false;\n\tdisableRebasing?: boolean;\n\trebaseTimeout?: number;\n\t/**\n\t * Provide a specific schema number to override the schema version\n\t * in the database. This is useful for testing migrations or recovering\n\t * from a mistakenly deployed incorrect schema. A specific version is required\n\t * so that you don't leave this on accidentally for all new schemas.\n\t */\n\toverrideSchemaConflict?: number;\n\t/**\n\t * Configuration for file management\n\t */\n\tfiles?: FileConfig;\n\n\t/**\n\t * Override the default IndexedDB persistence implementation.\n\t */\n\tpersistence?: PersistenceImplementation;\n\n\t/**\n\t * Specify the environment dependencies needed for the client.\n\t * Normally these are provided by the browser, but in other\n\t * runtimes you may need to provide your own.\n\t */\n\tenvironment?: Partial<ContextEnvironment>;\n\n\t/**\n\t * Enables experimental WeakRef usage to cull documents\n\t * from cache that aren't being used. This is a performance\n\t * optimization which has been tested under all Verdant's test\n\t * suites but I still want to keep testing it in the real world\n\t * before turning it on.\n\t */\n\tEXPERIMENTAL_weakRefs?: boolean;\n\n\t/**\n\t * Customize querying behavior.\n\t */\n\tqueries?: QueryConfig;\n\n\tpersistenceShutdownHandler?: ShutdownHandler;\n}\n\n/**\n * Common components utilized across various client\n * services.\n */\nexport class Context {\n\tnamespace: string;\n\t/**\n\t * when in WIP mode, namespace might be set to a temporary value. This will always point to the\n\t * namespace the user passed in.\n\t */\n\toriginalNamespace: string;\n\ttime: Time;\n\n\t// async initialized services\n\tget meta(): Promise<PersistenceMetadata> {\n\t\treturn this.initializedPromise.then((init) => init.meta);\n\t}\n\tget documents(): Promise<PersistenceDocuments> {\n\t\treturn this.initializedPromise.then((init) => init.documents);\n\t}\n\tget files(): Promise<PersistenceFiles> {\n\t\treturn this.initializedPromise.then((init) => init.files);\n\t}\n\n\tundoHistory: UndoHistory;\n\tschema: StorageSchema;\n\toldSchemas: StorageSchema[];\n\tlog: VerdantLogger;\n\tentityEvents: EventSubscriber<{\n\t\tcollectionsChanged: (names: string[]) => void;\n\t\tdocumentChanged: (oid: ObjectIdentifier) => void;\n\t}>;\n\tinternalEvents: EventSubscriber<{\n\t\t/**\n\t\t * Fired when persisted data changes fundamentally, like resetting to 0,\n\t\t * or importing different data.\n\t\t */\n\t\tpersistenceReset: () => void;\n\t\tfilesDeleted: (files: FileRef[]) => void;\n\t\tfileAdded: (file: FileData) => void;\n\t\t[ev: `fileUploaded:${string}`]: (file: FileData) => void;\n\t\tfileUploaded: (file: FileData) => void;\n\t\toutgoingSyncMessage: (message: ClientMessage) => void;\n\t}>;\n\tglobalEvents: EventSubscriber<{\n\t\t/**\n\t\t * A change from a future version of the application has been\n\t\t * witnessed. These changes are not applied but it indicates\n\t\t * the app has been updated and we should prompt the user\n\t\t * to reload or have their app user manually reload.\n\t\t *\n\t\t * The parameter is the timestamp of the future change.\n\t\t */\n\t\tfutureSeen: (timestamp: string) => void;\n\t\t/**\n\t\t * The server requested this replica reset its state\n\t\t * completely. This can happen when the replica has\n\t\t * been offline for too long and reconnects.\n\t\t */\n\t\tresetToServer: () => void;\n\t\t/**\n\t\t * An operation has been processed by the system. This could be a locally sourced\n\t\t * operation or a remote operation from sync.\n\t\t */\n\t\toperation: (operation: Operation) => void;\n\t\t/**\n\t\t * Emitted when storage rebases history. This should never actually affect application behavior\n\t\t * or stored data, but is useful for debugging and testing.\n\t\t */\n\t\trebase: () => void;\n\t\tfileSaved: (file: FileData) => void;\n\t}>;\n\tweakRef = <T extends object>(value: T): WeakRef<T> => {\n\t\tif (this.init.EXPERIMENTAL_weakRefs) {\n\t\t\treturn new WeakRef(value);\n\t\t}\n\t\treturn new FakeWeakRef(value) as any;\n\t};\n\tmigrations: Migration<any>[];\n\t/** If this is present, any attempt to close the client should await it first. */\n\tcloseLock?: Promise<void>;\n\tpatchCreator: PatchCreator;\n\tpersistenceShutdownHandler: ShutdownHandler;\n\n\t// state\n\tclosing: boolean = false;\n\tpauseRebasing: boolean = false;\n\n\tconfig: {\n\t\tfiles?: FileConfig;\n\t\tsync?: SyncConfig;\n\t\tpersistence?: PersistenceConfig;\n\t\tqueries?: QueryConfig;\n\t};\n\n\tenvironment: ContextEnvironment;\n\n\tpersistence: PersistenceImplementation;\n\n\t/**\n\t * Must be defined by the Client once it exists. Attempts to use this before\n\t * it's ready will rightfully throw an error.\n\t */\n\tgetClient = (): Client => {\n\t\tthrow new VerdantError(\n\t\t\tVerdantError.Code.Unexpected,\n\t\t\tundefined,\n\t\t\t'Client not yet initialized. This is a Verdant bug, please report it.',\n\t\t);\n\t};\n\n\tconstructor(\n\t\tprivate init: ContextInit,\n\t\tinitPersistence?: ReturnType<typeof initializePersistence>,\n\t) {\n\t\t// if server-side and no alternative IndexedDB implementation was provided,\n\t\t// we can't initialize the storage\n\t\tif (typeof window === 'undefined' && !this.init.environment) {\n\t\t\tthrow new Error(\n\t\t\t\t'A Verdant client was initialized in an environment without a global Window or `environment` configuration. If you are using verdant in a server-rendered framework, you must enforce that all clients are initialized on the client-side, or you must provide some mock interface of the environment to the Client options.',\n\t\t\t);\n\t\t}\n\t\t// set static values\n\t\tthis.namespace = this.init.namespace;\n\t\tthis.originalNamespace = this.init.namespace;\n\t\tthis.time = new Time(\n\t\t\tnew HybridLogicalClockTimestampProvider(),\n\t\t\tthis.init.schema.version,\n\t\t);\n\t\tthis.log =\n\t\t\tthis.init.log === false ? noLogger : this.init.log || debugLogger('\uD83C\uDF3F');\n\t\tthis.migrations = init.migrations;\n\t\tthis.undoHistory = init.undoHistory || new UndoHistory();\n\t\tthis.entityEvents = new EventSubscriber();\n\t\tthis.internalEvents = new EventSubscriber();\n\t\tthis.globalEvents = new EventSubscriber();\n\t\tthis.schema = init.schema;\n\t\tthis.oldSchemas = init.oldSchemas;\n\t\tthis.patchCreator = new PatchCreator(() => this.time.now);\n\t\tthis.persistenceShutdownHandler =\n\t\t\tinit.persistenceShutdownHandler || new ShutdownHandler(this.log);\n\t\tthis.config = {\n\t\t\tfiles: init.files,\n\t\t\tsync: init.sync,\n\t\t\tpersistence: {\n\t\t\t\tdisableRebasing: init.disableRebasing,\n\t\t\t\trebaseTimeout: init.rebaseTimeout,\n\t\t\t},\n\t\t\tqueries: init.queries,\n\t\t};\n\t\tthis.environment = {\n\t\t\t...defaultBrowserEnvironment,\n\t\t\t...init.environment,\n\t\t};\n\t\tthis.persistence =\n\t\t\tinit.persistence || new IdbPersistence(this.environment.indexedDB);\n\t\tthis.initializedPromise = initPersistence || initializePersistence(this);\n\t\tthis.initializedPromise.then(() => {\n\t\t\tthis.log('info', 'Persistence initialized');\n\t\t});\n\t}\n\tprivate initializedPromise;\n\tget waitForInitialization(): Promise<void> {\n\t\treturn this.initializedPromise.then(() => {});\n\t}\n\treinitialize = async (): Promise<void> => {\n\t\tthis.initializedPromise = initializePersistence(this);\n\t\tawait this.initializedPromise;\n\t};\n\n\tcloneWithOptions(options: Partial<ContextInit>): Context {\n\t\tconst copy = new Context(\n\t\t\t{ ...this.init, ...options },\n\t\t\tthis.initializedPromise,\n\t\t);\n\t\treturn copy;\n\t}\n}\n\nexport interface FileConfig {\n\t/**\n\t * Override the heuristic for deciding when a deleted file can be cleaned up.\n\t * By default this waits 3 days since deletion, then deletes the file data.\n\t * If the file has been synchronized to a server, it could still be restored\n\t * if the server has not yet deleted it.\n\t */\n\tcanCleanupDeletedFile?: (file: PersistedFileData) => boolean;\n}\n\nexport interface ServerSyncEndpointProviderConfig {\n\t/**\n\t * The location of the endpoint used to retrieve an\n\t * authorization token for the client.\n\t */\n\tauthEndpoint?: string;\n\t/**\n\t * A custom function to retrieve authorization\n\t * data. Use whatever fetching mechanism you want.\n\t */\n\tfetchAuth?: () => Promise<{\n\t\taccessToken: string;\n\t}>;\n\t/**\n\t * A spec-compliant fetch implementation. If not provided,\n\t * the global fetch will be used. authEndpoint will\n\t * be used to fetch the token.\n\t */\n\tfetch?: typeof fetch;\n}\n\nexport type SyncTransportMode = 'realtime' | 'pull';\n\nexport interface SyncConfig<Profile = any, Presence = any>\n\textends ServerSyncEndpointProviderConfig {\n\t/**\n\t * When a client first connects, it will use this presence value.\n\t */\n\tinitialPresence: Presence;\n\t/**\n\t * Before connecting to the server, the local client will have\n\t * this value for their profile data. You can either cache and store\n\t * profile data from a previous connection or provide defaults like\n\t * empty strings.\n\t */\n\tdefaultProfile: Profile;\n\n\t/**\n\t * Provide `false` to disable transport selection. Transport selection\n\t * automatically switches between HTTP and WebSocket based sync depending\n\t * on the number of peers connected. If a user is alone, they will use\n\t * HTTP push/pull to sync changes. If another user joins, both users will\n\t * be upgraded to websockets.\n\t *\n\t * Provide `peers-only` to only automatically use websockets if other\n\t * users connect, but not if another device for the current user connects.\n\t * By default, automatic transport selection will upgrade to websockets if\n\t * another device from the current user connects, but if realtime sync is\n\t * not necessary for such cases, you can save bandwidth by disabling this.\n\t *\n\t * Turning off this feature allows you more control over the transport\n\t * which can be useful for low-power devices or to save server traffic.\n\t * To modify transport modes manually, utilize `client.sync.setMode`.\n\t * The built-in behavior is essentially switching modes based on\n\t * the number of peers detected by client.sync.presence.\n\t */\n\tautomaticTransportSelection?: boolean | 'peers-only';\n\tinitialTransport?: SyncTransportMode;\n\tautoStart?: boolean;\n\t/**\n\t * Optionally specify an interval, in milliseconds, to poll the server\n\t * when in pull mode.\n\t */\n\tpullInterval?: number;\n\t/**\n\t * Presence updates are batched to reduce number of requests / messages\n\t * sent to the server. You can specify the batching time slice, in milliseconds,\n\t */\n\tpresenceUpdateBatchTimeout?: number;\n\t/**\n\t * Experimental: sync messages over a broadcast channel between tabs.\n\t * Fixes tabs not reactively updating to changes when other tabs are open,\n\t * but is not yet thoroughly vetted.\n\t */\n\tuseBroadcastChannel?: boolean;\n\t/**\n\t * Listen for outgoing messages from the client to the server.\n\t * Not sure why you want to do this, but be careful.\n\t */\n\tonOutgoingMessage?: (message: ClientMessage) => void;\n\n\tEXPERIMENTAL_backgroundSync?: boolean;\n}\n\nexport interface PersistenceConfig {\n\tdisableRebasing?: boolean;\n\trebaseTimeout?: number;\n}\n\nexport interface QueryConfig {\n\t/**\n\t * Milliseconds to hold a query in memory after it is unsubscribed before\n\t * disposing of it. Once a query is disposed, it must be loaded fresh again\n\t * on next use. Queries are cached based on their `key`, which you can\n\t * manually override. By default keys are determined by the parameters\n\t * passed to the query.\n\t *\n\t * Defaults to 5 seconds.\n\t */\n\tevictionTime?: number;\n}\n\nexport type ContextWithoutPersistence = Omit<\n\tContext,\n\t'meta' | 'documents' | 'files'\n>;\n", "import {\n\taddFieldDefaults,\n\tassert,\n\tAuthorizationKey,\n\tconstrainEntity,\n\tcreateOid,\n\tisRootOid,\n\tSchemaCollection,\n\tStorageCollectionSchema,\n\tStorageDocument,\n\tStorageSchema,\n} from '@verdant-web/common';\nimport { EntityCreateOptions, EntityStore } from '../entities/EntityStore.js';\nimport { ObjectEntity } from '../index.js';\n\n/**\n * Exposes functionality for creating documents,\n * the only mutation which is available as an entry\n * point in the storage system.\n */\nexport class DocumentManager<Schema extends StorageSchema<any>> {\n\tconstructor(\n\t\tprivate schema: Schema,\n\t\tprivate entities: EntityStore,\n\t) {}\n\n\tprivate getOid = (collection: string, init: any) => {\n\t\tconst primaryKeyName = this.schema.collections[collection]\n\t\t\t.primaryKey as Exclude<\n\t\t\tkeyof StorageDocument<SchemaCollection<Schema, any>>,\n\t\t\tsymbol\n\t\t>;\n\t\tconst primaryKey = init[primaryKeyName];\n\t\tassert(\n\t\t\tprimaryKey,\n\t\t\t`Document must have a primary key: ${primaryKeyName.toString()} (got: ${JSON.stringify(\n\t\t\t\tinit,\n\t\t\t)})`,\n\t\t);\n\t\treturn createOid(collection, primaryKey);\n\t};\n\n\tprivate addDefaults = (collectionName: string, init: any) => {\n\t\tconst collection = this.schema.collections[\n\t\t\tcollectionName\n\t\t] as StorageCollectionSchema;\n\t\treturn addFieldDefaults(collection, init);\n\t};\n\n\tprivate validate = (collectionName: string, init: any) => {\n\t\tconst collection = this.schema.collections[\n\t\t\tcollectionName\n\t\t] as StorageCollectionSchema;\n\t\treturn constrainEntity(collection.fields, init);\n\t};\n\n\tcreate = async (\n\t\tcollection: string,\n\t\tinit: any,\n\t\toptions: {\n\t\t\tundoable?: boolean;\n\t\t\taccess?: AuthorizationKey;\n\t\t\tsilenceAccessControlWithPrimaryKeyWarning?: boolean;\n\t\t} = {},\n\t) => {\n\t\tconst widenedOptions = options as EntityCreateOptions;\n\t\tconst defaulted = this.addDefaults(collection, init);\n\t\tconst validated = this.validate(collection, defaulted);\n\t\tconst oid = this.getOid(collection, validated);\n\n\t\tif (options.access) {\n\t\t\tconst collectionSchema = this.schema.collections[collection];\n\t\t\tif (\n\t\t\t\toptions.access !== 'shared' &&\n\t\t\t\tinit[collectionSchema.primaryKey] &&\n\t\t\t\t!options.silenceAccessControlWithPrimaryKeyWarning\n\t\t\t) {\n\t\t\t\t// using a custom primary key with access control is not supported.\n\t\t\t\t// resulting docs could collide with existing docs with different permissions,\n\t\t\t\t// leading to confusing results. this logs a warning.\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`Using a custom primary key with access control is not supported. This may result in corrupted documents. Read more about why: https://verdant.dev/docs/sync/access#a-warning-about-custom-primaryKey`,\n\t\t\t\t);\n\t\t\t}\n\t\t\twidenedOptions.access = options.access;\n\t\t}\n\n\t\t// documents are always objects at the root\n\t\treturn this.entities.create(validated, oid, widenedOptions) as any;\n\t};\n\n\tdelete = async (\n\t\tcollection: string,\n\t\tprimaryKey: string,\n\t\toptions: { undoable?: boolean } = {},\n\t) => {\n\t\tconst oid = createOid(collection, primaryKey);\n\t\treturn this.entities.delete(oid, options);\n\t};\n\n\tdeleteAll = async (\n\t\tids: [string, string][],\n\t\toptions: { undoable?: boolean } = {},\n\t) => {\n\t\treturn this.entities.deleteAll(\n\t\t\tids.map(([collection, primaryKey]) => createOid(collection, primaryKey)),\n\t\t\toptions,\n\t\t);\n\t};\n\n\tdeleteAllFromCollection = async (\n\t\tcollection: string,\n\t\tids: string[],\n\t\toptions: { undoable?: boolean } = {},\n\t) => {\n\t\treturn this.entities.deleteAll(\n\t\t\tids.map((primaryKey) => createOid(collection, primaryKey)),\n\t\t\toptions,\n\t\t);\n\t};\n\n\t/**\n\t * Creates a clone of the given document entity, returning a new\n\t * document entity in the given collection. The primary key of\n\t * the original document will be regenerated automatically and\n\t * access will be copied from the original. Both can be overridden\n\t * explicitly via options.\n\t */\n\tclone = async <TInit>(\n\t\tcollection: string,\n\t\tentity: ObjectEntity<TInit, any>,\n\t\toptions: {\n\t\t\tundoable?: boolean;\n\t\t\taccess?: AuthorizationKey;\n\t\t\tprimaryKey?: string;\n\t\t\t/**\n\t\t\t * Modify the data before cloning\n\t\t\t */\n\t\t\tupdate?: (init: TInit) => TInit;\n\t\t} = {},\n\t) => {\n\t\tif (!isRootOid(entity.uid)) {\n\t\t\tthrow new Error('Cannot clone non-root documents');\n\t\t}\n\t\t// take the entity snapshot\n\t\tconst snapshot = entity.getSnapshot() as any;\n\t\t// remove the primary key\n\t\tconst collectionSchema = this.schema.collections[collection];\n\t\tdelete snapshot[collectionSchema.primaryKey];\n\t\t// if collection schema's primary key doesn't have a default value,\n\t\t// a user-supplied value is required\n\t\tif (!collectionSchema.fields[collectionSchema.primaryKey].default) {\n\t\t\tif (!options.primaryKey) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Error cloning document from collection ${collection}: collection does not have a default on primary key. You must supply a value to options.primaryKey for the clone.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tsnapshot[collectionSchema.primaryKey] = options.primaryKey;\n\t\t}\n\t\t// copy authorization of original unless user supplied override\n\t\tif (entity.access && !options.access) {\n\t\t\toptions.access = entity.access;\n\t\t}\n\t\tconst final = options.update ? options.update(snapshot) : snapshot;\n\t\treturn this.create(collection, final, options);\n\t};\n}\n", "import {\n\tAuthorizationKey,\n\tDocumentBaseline,\n\tFileData,\n\tObjectIdentifier,\n\tOperation,\n\tStorageObjectFieldSchema,\n\tVerdantError,\n\tassert,\n\tassignOid,\n\tdecomposeOid,\n\tgetOidRoot,\n\tgroupBaselinesByRootOid,\n\tgroupPatchesByOid,\n\tgroupPatchesByRootOid,\n\tisRootOid,\n\tremoveOidsFromAllSubObjects,\n} from '@verdant-web/common';\nimport { WeakEvent } from 'weak-event';\nimport { Context } from '../context/context.js';\nimport { FileManager } from '../files/FileManager.js';\nimport { processValueFiles } from '../files/utils.js';\nimport { Disposable } from '../utils/Disposable.js';\nimport { Entity } from './Entity.js';\nimport { EntityFamilyMetadata } from './EntityMetadata.js';\nimport { OperationBatcher } from './OperationBatcher.js';\n\nenum AbortReason {\n\tReset,\n}\n\nexport type EntityStoreEventData = {\n\toid: ObjectIdentifier;\n\toperations?: Record<string, Operation[]>;\n\tbaselines?: DocumentBaseline[];\n\tisLocal: boolean;\n};\n\nexport type EntityStoreEvents = {\n\tadd: WeakEvent<EntityStore, EntityStoreEventData>;\n\treplace: WeakEvent<EntityStore, EntityStoreEventData>;\n\tresetAll: WeakEvent<EntityStore, void>;\n};\n\nexport interface IncomingData {\n\toperations?: Operation[];\n\tbaselines?: DocumentBaseline[];\n\treset?: boolean;\n\tisLocal?: boolean;\n}\n\nexport interface EntityCreateOptions {\n\tundoable?: boolean;\n\taccess?: AuthorizationKey;\n}\n\nexport class EntityStore extends Disposable {\n\tprivate ctx;\n\tprivate files;\n\tprivate batcher;\n\tprivate events: EntityStoreEvents = {\n\t\tadd: new WeakEvent(),\n\t\treplace: new WeakEvent(),\n\t\tresetAll: new WeakEvent(),\n\t};\n\tprivate cache = new Map<ObjectIdentifier, WeakRef<Entity>>();\n\tprivate pendingEntityPromises = new Map<\n\t\tObjectIdentifier,\n\t\tPromise<Entity | null>\n\t>();\n\t// halts the current data queue processing\n\tprivate abortDataQueueController = new AbortController();\n\tprivate ongoingResetPromise: Promise<void> | null = null;\n\tprivate entityFinalizationRegistry = new FinalizationRegistry(\n\t\t(oid: ObjectIdentifier) => {\n\t\t\tthis.ctx.log('debug', 'Entity GC', oid);\n\t\t},\n\t);\n\n\tconstructor({ ctx, files }: { ctx: Context; files: FileManager }) {\n\t\tsuper();\n\n\t\tthis.ctx = ctx;\n\t\tthis.files = files;\n\t\tthis.batcher = new OperationBatcher({\n\t\t\tctx,\n\t\t\tentities: this,\n\t\t});\n\t\tthis.addDispose(\n\t\t\tthis.ctx.internalEvents.subscribe('persistenceReset', this.clearCache),\n\t\t);\n\t}\n\n\t// expose batch APIs\n\tget batch() {\n\t\treturn this.batcher.batch;\n\t}\n\tget flushAllBatches() {\n\t\treturn this.batcher.flushAll;\n\t}\n\n\t// internal-ish API to load remote / stored data\n\taddData = async (data: IncomingData) => {\n\t\tif (this.disposed) {\n\t\t\tthis.ctx.log('warn', 'EntityStore is disposed, not adding incoming data');\n\t\t\treturn;\n\t\t}\n\t\t// for resets - abort any other changes, reset everything,\n\t\t// then proceed\n\t\tif (data.reset) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'info',\n\t\t\t\t'Resetting local store to replicate remote synced data - dropping any current transactions',\n\t\t\t);\n\t\t\t// cancel any other ongoing data - it will all\n\t\t\t// be replaced by the reset\n\t\t\tthis.abortDataQueueController.abort(AbortReason.Reset);\n\t\t\tthis.abortDataQueueController = new AbortController();\n\t\t\tthis.ongoingResetPromise = this.resetData().finally(() => {\n\t\t\t\tthis.ongoingResetPromise = null;\n\t\t\t\tthis.ctx.globalEvents.emit('resetToServer');\n\t\t\t});\n\t\t}\n\n\t\t// await either the reset we just started, or any that was\n\t\t// in progress when this data came in.\n\t\tif (this.ongoingResetPromise) {\n\t\t\tthis.ctx.log('debug', 'Waiting for ongoing reset to complete');\n\t\t\tawait this.ongoingResetPromise;\n\t\t\tthis.ctx.log('debug', 'Ongoing reset complete');\n\t\t}\n\n\t\tawait this.processData(data);\n\t};\n\n\tempty = async () => {\n\t\tawait (await this.ctx.documents).reset();\n\t\tthis.events.resetAll.invoke(this);\n\t\tthis.cache.clear();\n\t};\n\n\tprivate resetData = async () => {\n\t\tif (this.disposed) {\n\t\t\tthis.ctx.log('warn', 'EntityStore is disposed, not resetting local data');\n\t\t\treturn;\n\t\t}\n\t\tawait (await this.ctx.meta).reset();\n\t\tawait (await this.ctx.documents).reset();\n\t\tthis.events.resetAll.invoke(this);\n\t};\n\n\tprivate processData = async (data: IncomingData) => {\n\t\tif (this.disposed) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'warn',\n\t\t\t\t'EntityStore is disposed, not processing incoming data',\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst baselines = data?.baselines ?? [];\n\t\tconst operations = data?.operations ?? [];\n\n\t\tif (baselines.length === 0 && operations.length === 0) {\n\t\t\tthis.ctx.log('debug', 'No data to process');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.ctx.log('debug', 'Processing incoming data', {\n\t\t\toperations: operations.length,\n\t\t\tbaselines: baselines.length,\n\t\t\treset: !!data.reset,\n\t\t});\n\n\t\tconst allDocumentOids: ObjectIdentifier[] = Array.from(\n\t\t\tnew Set(\n\t\t\t\tbaselines\n\t\t\t\t\t.map((b) => getOidRoot(b.oid))\n\t\t\t\t\t.concat(operations.map((o) => getOidRoot(o.oid))),\n\t\t\t),\n\t\t);\n\t\tconst baselinesGroupedByOid = groupBaselinesByRootOid(baselines);\n\t\tconst operationsGroupedByOid = groupPatchesByRootOid(operations);\n\n\t\tthis.ctx.log('debug', 'Applying data to live entities');\n\t\t// synchronously add/replace data in any open entities via eventing\n\t\tfor (const oid of allDocumentOids) {\n\t\t\tconst baselines = baselinesGroupedByOid[oid];\n\t\t\tconst operations = operationsGroupedByOid[oid] ?? [];\n\t\t\tconst groupedOperations = groupPatchesByOid(operations);\n\t\t\t// what happens if an entity is being hydrated\n\t\t\t// while this is happening? - we wait for the hydration promise\n\t\t\t// to complete, then invoke the event\n\t\t\tconst event = data.reset ? this.events.replace : this.events.add;\n\t\t\tconst hydrationPromise = this.pendingEntityPromises.get(oid);\n\t\t\tif (hydrationPromise) {\n\t\t\t\tthis.ctx.log('debug', 'Waiting for ongoing entity hydration', oid);\n\t\t\t\thydrationPromise.then(() => {\n\t\t\t\t\tevent.invoke(this, {\n\t\t\t\t\t\toid,\n\t\t\t\t\t\tbaselines,\n\t\t\t\t\t\toperations: groupedOperations,\n\t\t\t\t\t\tisLocal: false,\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.ctx.log('debug', 'Applying data to entity', oid);\n\t\t\t\tevent.invoke(this, {\n\t\t\t\t\toid,\n\t\t\t\t\tbaselines,\n\t\t\t\t\toperations: groupedOperations,\n\t\t\t\t\tisLocal: false,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tconst abortOptions = {\n\t\t\tabort: this.abortDataQueueController.signal,\n\t\t};\n\n\t\t// then, asynchronously add to the database\n\t\t// this also emits messages to sync\n\t\t// TODO: could messages be sent to sync before storage,\n\t\t// so that realtime is lower latency? What would happen\n\t\t// if the storage failed?\n\t\tawait (await this.ctx.meta).insertData(data, abortOptions);\n\t\tthis.ctx.log(\n\t\t\t'debug',\n\t\t\t'Data processing complete, all data saved to metadata db.',\n\t\t);\n\n\t\t// recompute all affected documents for querying\n\t\tconst entities = await Promise.all(\n\t\t\tallDocumentOids.map(async (oid) => {\n\t\t\t\tconst entity = await this.hydrate(oid, abortOptions);\n\t\t\t\t// if the entity is not found, we return a stub that\n\t\t\t\t// indicates it's deleted and should be cleared\n\t\t\t\treturn (\n\t\t\t\t\tentity ?? {\n\t\t\t\t\t\toid,\n\t\t\t\t\t\tgetSnapshot(): any {\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\t\ttry {\n\t\t\tthis.ctx.log('debug', 'Saving entities to queryable storage');\n\t\t\tawait (await this.ctx.documents).saveEntities(entities, abortOptions);\n\t\t} catch (err) {\n\t\t\tif (this.disposed) {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'warn',\n\t\t\t\t\t'Error saving entities to queryable storage - EntityStore is disposed',\n\t\t\t\t\terr,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'error',\n\t\t\t\t\t'Error saving entities to queryable storage',\n\t\t\t\t\terr,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t};\n\n\t// internal-ish API for creating Entities from OIDs\n\t// when query results come in\n\thydrate = async (\n\t\toid: string,\n\t\topts?: { abort: AbortSignal },\n\t): Promise<Entity | null> => {\n\t\tif (!isRootOid(oid)) {\n\t\t\tthrow new Error('Cannot hydrate non-root entity');\n\t\t}\n\n\t\tif (this.cache.has(oid)) {\n\t\t\tconst cached = this.cache.get(oid);\n\t\t\tif (cached) {\n\t\t\t\tconst entity = cached.deref();\n\t\t\t\tif (entity) {\n\t\t\t\t\tif (entity.deleted) {\n\t\t\t\t\t\tthis.ctx.log('debug', 'Cached entity is deleted', oid);\n\t\t\t\t\t\t// debugger;\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tthis.ctx.log('debug', 'Using cached hydrated entity', oid);\n\t\t\t\t\treturn entity;\n\t\t\t\t} else {\n\t\t\t\t\tthis.ctx.log('debug', \"Removing GC'd entity from cache\", oid);\n\t\t\t\t\tthis.cache.delete(oid);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// we don't want to hydrate two entities in parallel, so\n\t\t// we use a promise to ensure that only one is ever\n\t\t// constructed at a time\n\t\tconst pendingPromise = this.pendingEntityPromises.get(oid);\n\t\tif (!pendingPromise) {\n\t\t\tthis.ctx.log('debug', 'Hydrating entity from storage', oid);\n\t\t\tconst entity = this.constructEntity(oid);\n\t\t\tif (!entity) {\n\t\t\t\tthis.ctx.log('warn', 'Entity schema not found, cannot construct', oid);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst pendingPromise = this.loadEntity(entity, opts);\n\t\t\tpendingPromise.finally(() => {\n\t\t\t\tthis.pendingEntityPromises.delete(oid);\n\t\t\t\tthis.ctx.log('debug', 'Hydration complete', oid);\n\t\t\t});\n\t\t\tthis.pendingEntityPromises.set(oid, pendingPromise);\n\t\t\treturn pendingPromise;\n\t\t} else {\n\t\t\tthis.ctx.log('debug', 'Waiting for ongoing entity hydration', oid);\n\t\t\treturn pendingPromise;\n\t\t}\n\t};\n\n\tdestroy = async () => {\n\t\tthis.ctx.log('warn', 'Disposing EntityStore');\n\t\tthis.dispose();\n\t\tawait this.batcher.flushAll();\n\t};\n\n\t// public APIs for manipulating entities\n\n\t/**\n\t * Creates a new Entity with the given initial data.\n\t */\n\tcreate = async (\n\t\tinitial: any,\n\t\toid: ObjectIdentifier,\n\t\t{ undoable = true, access }: EntityCreateOptions = {},\n\t) => {\n\t\tthis.ctx.log('debug', 'Creating new entity', oid);\n\t\tconst { collection } = decomposeOid(oid);\n\t\t// remove any OID associations from the initial data\n\t\tremoveOidsFromAllSubObjects(initial);\n\t\t// grab files and replace them with refs\n\t\tconst fileRefs: FileData[] = [];\n\t\tconst processed = processValueFiles(initial, fileRefs.push.bind(fileRefs));\n\n\t\tassignOid(processed, oid);\n\n\t\t// validate that schema exists\n\t\tconst { schema } = this.getCollectionSchema(collection);\n\t\tif (!schema) {\n\t\t\tthrow new Error(`Collection schema not found for ${collection}`);\n\t\t}\n\n\t\tconst operations = this.ctx.patchCreator.createInitialize(\n\t\t\tprocessed,\n\t\t\toid,\n\t\t\taccess,\n\t\t);\n\t\tawait this.batcher.commitOperations(operations, {\n\t\t\tundoable: !!undoable,\n\t\t});\n\n\t\t// TODONE: what happens if you create an entity with an OID that already\n\t\t// exists?\n\t\t// A: it will overwrite the existing entity\n\n\t\t// wait for the entity to load and cache before returning\n\t\tconst entity = await this.hydrate(oid);\n\t\tif (!entity) {\n\t\t\t// something failed when creating the entity\n\t\t\tthis.ctx.log(\n\t\t\t\t'error',\n\t\t\t\t'Failed to create entity; hydrated entity is null. Hopefully an error is logged above.',\n\t\t\t\toid,\n\t\t\t);\n\t\t\tthrow new VerdantError(\n\t\t\t\tVerdantError.Code.Unexpected,\n\t\t\t\tundefined,\n\t\t\t\t`Failed to create document ${oid}`,\n\t\t\t);\n\t\t}\n\t\t// add files with entity as parent\n\t\t// note: these .add invocations have async behavior -- it should upload any files to the\n\t\t// server if sync is active. but we don't need to wait for it to make the entity usable as file\n\t\t// data should already be locally available.\n\t\tthis.ctx.log(\n\t\t\t'debug',\n\t\t\t'Associating',\n\t\t\tfileRefs.length,\n\t\t\t'files to new entity',\n\t\t\toid,\n\t\t);\n\t\tfileRefs.forEach((file) => this.files.add(file, entity));\n\t\treturn entity;\n\t};\n\n\tdeleteAll = async (\n\t\toids: ObjectIdentifier[],\n\t\toptions?: { undoable?: boolean },\n\t) => {\n\t\tthis.ctx.log('info', 'Deleting documents', oids);\n\t\tassert(\n\t\t\toids.every((oid) => oid === getOidRoot(oid)),\n\t\t\t'Only root documents may be deleted via client methods',\n\t\t);\n\n\t\tconst entities = await Promise.all(oids.map((oid) => this.hydrate(oid)));\n\n\t\tconst operations: Operation[] = [];\n\t\tfor (const entity of entities) {\n\t\t\tif (entity) {\n\t\t\t\tconst oids = entity.__getFamilyOids__();\n\t\t\t\tconst deletes = this.ctx.patchCreator.createDeleteAll(oids);\n\t\t\t\tfor (const op of deletes) {\n\t\t\t\t\top.authz = entity.access;\n\t\t\t\t}\n\t\t\t\toperations.push(...deletes);\n\t\t\t}\n\t\t}\n\n\t\tawait this.batcher.commitOperations(operations, {\n\t\t\tundoable: options?.undoable === undefined ? true : options.undoable,\n\t\t});\n\n\t\t// remove the entities from cache\n\t\toids.forEach((oid) => {\n\t\t\tthis.cache.delete(oid);\n\t\t\tthis.ctx.log('debug', 'Deleted document from cache', oid);\n\t\t});\n\t};\n\n\tdelete = async (oid: ObjectIdentifier, options?: { undoable?: boolean }) => {\n\t\treturn this.deleteAll([oid], options);\n\t};\n\n\tprivate getCollectionSchema = (\n\t\tcollectionName: string,\n\t): {\n\t\tschema: StorageObjectFieldSchema<any> | null;\n\t\treadonlyKeys: string[];\n\t} => {\n\t\tconst schema = this.ctx.schema.collections[collectionName];\n\t\tif (!schema) {\n\t\t\tthis.ctx.log('warn', `Missing schema for collection: ${collectionName}`);\n\t\t\treturn {\n\t\t\t\tschema: null,\n\t\t\t\treadonlyKeys: [],\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\t// convert to object schema for compatibility\n\t\t\tschema: {\n\t\t\t\ttype: 'object',\n\t\t\t\tnullable: false,\n\t\t\t\tproperties: schema.fields as any,\n\t\t\t},\n\t\t\treadonlyKeys: [schema.primaryKey],\n\t\t};\n\t};\n\n\t/**\n\t * Constructs an entity from an OID, but does not load it or add it to the cache.\n\t */\n\tprivate constructEntity = (oid: string): Entity | null => {\n\t\tassert(!!oid, 'Cannot construct entity without OID');\n\t\tconst { collection } = decomposeOid(oid);\n\t\tconst { schema, readonlyKeys } = this.getCollectionSchema(collection);\n\n\t\tif (!schema) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (this.disposed) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'warn',\n\t\t\t\t'Cannot hydrate entity after store has been disposed',\n\t\t\t);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst metadataFamily = new EntityFamilyMetadata({\n\t\t\tctx: this.ctx,\n\t\t\tonPendingOperations: this.onPendingOperations,\n\t\t\trootOid: oid,\n\t\t});\n\n\t\t// this is created synchronously so it's immediately available\n\t\t// to begin capturing incoming data.\n\t\treturn new Entity({\n\t\t\tctx: this.ctx,\n\t\t\toid,\n\t\t\tschema,\n\t\t\treadonlyKeys,\n\t\t\tfiles: this.files,\n\t\t\tmetadataFamily: metadataFamily,\n\t\t\tstoreEvents: this.events,\n\t\t\tdeleteSelf: this.delete.bind(this, oid),\n\t\t});\n\t};\n\n\tprivate onPendingOperations = (operations: Operation[]) => {\n\t\tthis.batcher.addOperations(operations);\n\t};\n\n\tdiscardPendingOperation = (operation: Operation) => {\n\t\tconst root = getOidRoot(operation.oid);\n\t\tthis.cache.get(root)?.deref()?.__discardPendingOperation__(operation);\n\t};\n\n\t/**\n\t * Loads initial Entity data from storage\n\t */\n\tprivate loadEntity = async (\n\t\tentity: Entity,\n\t\topts?: { abort: AbortSignal },\n\t): Promise<Entity | null> => {\n\t\tawait this.loadEntityData(entity, opts);\n\n\t\t// only set the cache after loading.\n\t\t// TODO: is this cache/promise stuff redundant?\n\t\tthis.cache.set(entity.oid, this.ctx.weakRef(entity));\n\t\tthis.entityFinalizationRegistry.register(entity, entity.oid);\n\n\t\treturn entity;\n\t};\n\n\tprivate loadEntityData = async (\n\t\tentity: Entity,\n\t\topts?: { abort: AbortSignal },\n\t) => {\n\t\tconst { operations, baselines } = await (\n\t\t\tawait this.ctx.meta\n\t\t).getDocumentData(entity.oid, opts);\n\n\t\tif (!baselines.length && !Object.keys(operations).length) {\n\t\t\tthis.ctx.log('debug', 'No data found for entity', entity.oid);\n\t\t\treturn null;\n\t\t}\n\n\t\tthis.ctx.log('debug', 'Loaded entity from storage', entity.oid);\n\n\t\tthis.events.replace.invoke(this, {\n\t\t\toid: entity.oid,\n\t\t\tbaselines,\n\t\t\toperations,\n\t\t\tisLocal: false,\n\t\t});\n\n\t\treturn entity;\n\t};\n\n\t/**\n\t * Drops all entities from the cache. Any entities\n\t * referenced will go 'dead'...\n\t */\n\tclearCache = () => {\n\t\tthis.ctx.log('debug', 'Emptying entity cache');\n\t\tthis.cache.clear();\n\t};\n}\n", "import {\n\tcreateFileRef,\n\tFileData,\n\tisFile,\n\tisFileData,\n} from '@verdant-web/common';\nimport cuid from 'cuid';\n\nexport function createFileData(file: File): FileData {\n\treturn {\n\t\tid: cuid(),\n\t\tfile: file,\n\t\turl: undefined,\n\t\tremote: false,\n\t\tname: file.name,\n\t\ttype: file.type,\n\t};\n}\n\n/**\n * MUTATES the value.\n * Replaces File values with refs and returns the normalized value.\n * The list of files passed to the second argument will be populated with the files found in the value.\n */\nexport function processValueFiles(\n\tvalue: any,\n\tonFileIdentified: (fileData: FileData) => void,\n): any {\n\tif (typeof window !== 'undefined' && isFile(value)) {\n\t\tconst data = createFileData(value);\n\t\tonFileIdentified(data);\n\t\treturn createFileRef(data.id);\n\t}\n\n\tif (isFileData(value)) {\n\t\t// create a new ID for the file\n\t\tconst cloned = { ...value, id: cuid() };\n\t\tonFileIdentified(cloned);\n\t\treturn createFileRef(cloned.id);\n\t}\n\n\tif (Array.isArray(value)) {\n\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\tvalue[i] = processValueFiles(value[i], onFileIdentified);\n\t\t}\n\t\treturn value;\n\t}\n\n\tif (typeof value === 'object') {\n\t\tfor (const key in value) {\n\t\t\tvalue[key] = processValueFiles(value[key], onFileIdentified);\n\t\t}\n\t\treturn value;\n\t}\n\n\treturn value;\n}\n", "import { EventSubscriber, FileData } from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { Entity } from '../entities/Entity.js';\n\nexport type EntityFileEvents = {\n\tchange: () => void;\n};\n\nexport const UPDATE = Symbol('entity-file-update');\nexport const MARK_FAILED = Symbol('entity-file-mark-failed');\n\n// this one goes on Entity\nexport const CHILD_FILE_CHANGED = Symbol('child-file-changed');\n\nexport type EntityFileSnapshot = {\n\tid: string;\n\turl?: string | null;\n};\n\n/**\n * Provides a consistent interface for files used in an app via\n * Entity access.\n */\nexport class EntityFile extends EventSubscriber<EntityFileEvents> {\n\t// cached object URL for a local blob file, if applicable\n\tprivate _objectUrl: string | null = null;\n\tprivate _fileData: FileData | null = null;\n\tprivate _loading = true;\n\tprivate _failed = false;\n\tprivate _failedReason: string | undefined;\n\tprivate _downloadRemote = false;\n\tprivate _uploaded = false;\n\tprivate ctx: Context;\n\tprivate unsubscribes: (() => void)[] = [];\n\tprivate parent: Entity;\n\n\tconstructor(\n\t\tpublic readonly id: string,\n\t\t{\n\t\t\tdownloadRemote = false,\n\t\t\tctx,\n\t\t\tparent,\n\t\t}: {\n\t\t\tdownloadRemote?: boolean;\n\t\t\tctx: Context;\n\t\t\tparent: Entity;\n\t\t},\n\t) {\n\t\tsuper();\n\t\tthis.ctx = ctx;\n\t\tthis.parent = parent;\n\t\tthis._downloadRemote = downloadRemote;\n\n\t\tthis.unsubscribes.push(\n\t\t\tthis.ctx.internalEvents.subscribe(`fileUploaded:${id}`, this.onUploaded),\n\t\t);\n\t}\n\n\tget downloadRemote() {\n\t\treturn this._downloadRemote;\n\t}\n\tget isFile() {\n\t\treturn true;\n\t}\n\tget isUploaded() {\n\t\treturn this._uploaded || this._fileData?.remote || false;\n\t}\n\tget error() {\n\t\treturn this._failedReason || null;\n\t}\n\n\tprivate emitChange() {\n\t\tthis.parent[CHILD_FILE_CHANGED](this);\n\t\tthis.emit('change');\n\t}\n\n\t[UPDATE] = (fileData: FileData) => {\n\t\tthis.ctx.log('debug', 'EntityFile updated', this.id, fileData);\n\t\tthis._loading = false;\n\t\tthis._failed = false;\n\t\tthis._fileData = fileData;\n\t\tif (fileData.file) {\n\t\t\tif (this._objectUrl && 'revokeObjectURL' in URL) {\n\t\t\t\tURL.revokeObjectURL(this._objectUrl);\n\t\t\t}\n\t\t\tthis.ctx.log('debug', 'Creating object URL for file', this.id);\n\t\t\tthis._objectUrl = URL.createObjectURL(fileData.file);\n\t\t}\n\t\tthis.emitChange();\n\t};\n\n\t[MARK_FAILED] = (reason?: string) => {\n\t\tthis._failed = true;\n\t\tthis._failedReason = reason;\n\t\tthis._loading = false;\n\t\tthis.emitChange();\n\t};\n\n\tprivate onUploaded = (data: FileData) => {\n\t\t// TODO: cleanup all this uploaded flagging junk\n\t\tthis._fileData ??= data;\n\t\tthis._uploaded = true;\n\t\tthis.ctx.log('debug', 'File marked uploaded', this.id, this._fileData);\n\t\tthis.emitChange();\n\t};\n\n\tget url(): string | null {\n\t\t// prefer local file representations.\n\t\tif (this.loading) return null;\n\t\tif (this._objectUrl) return this._objectUrl;\n\t\t// TODO: use localPath here?\n\t\treturn this._fileData?.url ?? null;\n\t}\n\n\tget name(): string | null {\n\t\treturn this._fileData?.name ?? null;\n\t}\n\n\tget type(): string | null {\n\t\treturn this._fileData?.type ?? null;\n\t}\n\n\tget loading() {\n\t\treturn this._loading;\n\t}\n\n\tget failed() {\n\t\treturn this._failed;\n\t}\n\n\tdestroy = () => {\n\t\tif (this._objectUrl) {\n\t\t\tURL.revokeObjectURL(this._objectUrl);\n\t\t}\n\t\tthis.dispose();\n\t};\n\n\tgetSnapshot(): FileData {\n\t\treturn {\n\t\t\tid: this.id,\n\t\t\turl: this._fileData?.url ?? this._objectUrl ?? undefined,\n\t\t\tname: this.name ?? 'unknown-file',\n\t\t\tremote: this._fileData?.remote ?? false,\n\t\t\ttype: this.type ?? '',\n\t\t\tfile: this._fileData?.file,\n\t\t};\n\t}\n}\n", "import { ObjectIdentifier } from '@verdant-web/common';\nimport { Context } from '../internal.js';\nimport { Entity, EntityInit } from './Entity.js';\n\nexport class EntityCache {\n\tprivate ctx: Context;\n\tprivate cache = new Map<string, WeakRef<Entity>>();\n\n\tconstructor({ initial, ctx }: { initial?: Entity[]; ctx: Context }) {\n\t\tthis.ctx = ctx;\n\t\tif (initial) {\n\t\t\tfor (const entity of initial) {\n\t\t\t\tthis.cache.set(entity.oid, ctx.weakRef(entity));\n\t\t\t}\n\t\t}\n\t}\n\n\tget = (init: EntityInit): Entity => {\n\t\tconst cached = this.getCached(init.oid);\n\t\tif (cached) return cached;\n\t\tconst entity = new Entity(init);\n\t\tthis.cache.set(init.oid, this.ctx.weakRef(entity));\n\t\treturn entity;\n\t};\n\n\thas = (oid: ObjectIdentifier) => {\n\t\treturn this.cache.has(oid);\n\t};\n\n\tgetCached = (oid: string) => {\n\t\tif (this.cache.has(oid)) {\n\t\t\tconst ref = this.cache.get(oid);\n\t\t\tconst derefed = ref?.deref();\n\t\t\tif (derefed) {\n\t\t\t\treturn derefed as Entity;\n\t\t\t} else {\n\t\t\t\tthis.cache.delete(oid);\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t};\n}\n", "import { Entity } from './Entity.js';\nimport { EntityChangeInfo } from './types.js';\n\nexport function entityFieldSubscriber<T = any>(\n\tentity: Entity,\n\tfield: string | number | symbol,\n\tsubscriber: (\n\t\tnewValue: T,\n\t\tinfo: EntityChangeInfo & { previousValue: T },\n\t) => void,\n) {\n\tconst valueHolder = {\n\t\tpreviousValue: entity.get(field),\n\t\tisLocal: false,\n\t};\n\tfunction handler(\n\t\tthis: { previousValue: T } & EntityChangeInfo,\n\t\tinfo: EntityChangeInfo,\n\t) {\n\t\tif (entity.deleted) {\n\t\t\treturn;\n\t\t}\n\t\tconst newValue = entity.get(field);\n\t\tif (newValue !== this.previousValue) {\n\t\t\tthis.isLocal = info.isLocal;\n\t\t\tsubscriber(newValue, this);\n\t\t\tthis.previousValue = newValue;\n\t\t}\n\t}\n\treturn entity.subscribe('change', handler.bind(valueHolder));\n}\n", "import {\n\tEntityValidationProblem,\n\tEventSubscriber,\n\tObjectIdentifier,\n\tOperation,\n\tStorageFieldSchema,\n\tassert,\n\tassignOid,\n\tcloneDeep,\n\tcompareRefs,\n\tcreateFileRef,\n\tcreateRef,\n\tcreateSubOid,\n\tgetChildFieldSchema,\n\tgetFieldDefault,\n\thasDefault,\n\tisFile,\n\tisFileRef,\n\tisNullable,\n\tisObject,\n\tisObjectRef,\n\tisPrimitive,\n\tisRef,\n\tmaybeGetOid,\n\tmemoByKeys,\n\ttraverseCollectionFieldsAndApplyDefaults,\n\tvalidateEntityField,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { CHILD_FILE_CHANGED } from '../files/EntityFile.js';\nimport { FileManager } from '../files/FileManager.js';\nimport { processValueFiles } from '../files/utils.js';\nimport { ClientWithCollections, EntityFile } from '../index.js';\nimport { EntityCache } from './EntityCache.js';\nimport { EntityFamilyMetadata, EntityMetadataView } from './EntityMetadata.js';\nimport { EntityStoreEventData, EntityStoreEvents } from './EntityStore.js';\nimport { entityFieldSubscriber } from './entityFieldSubscriber.js';\nimport {\n\tAnyEntity,\n\tBaseEntityValue,\n\tDataFromInit,\n\tEntityChange,\n\tEntityEvents,\n\tListEntity,\n\tListItemInit,\n\tListItemValue,\n\tObjectEntity,\n} from './types.js';\n\nexport interface EntityInit {\n\toid: ObjectIdentifier;\n\tschema: StorageFieldSchema;\n\tentityFamily?: EntityCache;\n\tmetadataFamily: EntityFamilyMetadata;\n\tparent?: Entity;\n\tctx: Context;\n\tfiles: FileManager;\n\treadonlyKeys?: string[];\n\tfieldPath?: (string | number)[];\n\tstoreEvents: EntityStoreEvents;\n\tdeleteSelf: () => void;\n}\n\nconst PRIVATE_ENTITY_CONTEXT_KEY = Symbol('private entity context key');\n\nexport class Entity<\n\t\tInit = any,\n\t\tKeyValue extends BaseEntityValue = any,\n\t\tSnapshot extends any = DataFromInit<Init>,\n\t>\n\textends EventSubscriber<EntityEvents>\n\timplements\n\t\tObjectEntity<Init, KeyValue, Snapshot>,\n\t\tListEntity<Init, KeyValue, Snapshot>\n{\n\treadonly oid: ObjectIdentifier;\n\tprivate readonlyKeys: string[];\n\tprivate fieldPath: (string | number)[] = [];\n\t// these are shared between all entities in this family\n\tprivate entityFamily: EntityCache;\n\tprivate metadataFamily;\n\n\treadonly schema;\n\tprivate parent: Entity | undefined;\n\tprivate ctx;\n\tprivate files;\n\tprivate storeEvents;\n\n\tget [PRIVATE_ENTITY_CONTEXT_KEY]() {\n\t\treturn this.ctx;\n\t}\n\n\t// an internal representation of this Entity.\n\t// if present, this is the cached, known value. If null,\n\t// the entity is deleted. If undefined, we need to recompute\n\t// the view.\n\tprivate _viewData: EntityMetadataView | undefined = undefined;\n\tprivate validationError: EntityValidationProblem | undefined = undefined;\n\tprivate cachedDeepUpdatedAt: number | null = null;\n\t// only used for root entities to track delete/restore state.\n\tprivate wasDeletedLastChange = false;\n\tprivate cachedView: any | undefined = undefined;\n\t// provided from external creators, this is a method to delete\n\t// this entity.\n\tprivate _deleteSelf: () => void;\n\n\tconstructor({\n\t\toid,\n\t\tschema,\n\t\tentityFamily: childCache,\n\t\tparent,\n\t\tctx,\n\t\tmetadataFamily,\n\t\treadonlyKeys,\n\t\tfiles,\n\t\tstoreEvents,\n\t\tdeleteSelf,\n\t\tfieldPath,\n\t}: EntityInit) {\n\t\tsuper();\n\n\t\tassert(!!oid, 'oid is required');\n\n\t\tthis.oid = oid;\n\t\tthis.readonlyKeys = readonlyKeys || [];\n\t\tthis.ctx = ctx;\n\t\tthis.files = files;\n\t\tthis.schema = schema;\n\t\tthis.fieldPath = fieldPath || [];\n\t\tthis.entityFamily =\n\t\t\tchildCache ||\n\t\t\tnew EntityCache({\n\t\t\t\tinitial: [this],\n\t\t\t\tctx,\n\t\t\t});\n\t\tthis.metadataFamily = metadataFamily;\n\t\tthis.storeEvents = storeEvents;\n\t\tthis.parent = parent;\n\t\tthis._deleteSelf = deleteSelf;\n\n\t\t// TODO: should any but the root entity be listening to these?\n\t\tif (!this.parent) {\n\t\t\tstoreEvents.add.attach(this.onAdd);\n\t\t\tstoreEvents.replace.attach(this.onReplace);\n\t\t\tstoreEvents.resetAll.attach(this.onResetAll);\n\t\t}\n\t}\n\n\tprivate onAdd = (_store: any, data: EntityStoreEventData) => {\n\t\tif (data.oid === this.oid) {\n\t\t\tthis.addConfirmedData(data);\n\t\t}\n\t};\n\tprivate onReplace = (_store: any, data: EntityStoreEventData) => {\n\t\tif (data.oid === this.oid) {\n\t\t\tthis.replaceAllData(data);\n\t\t}\n\t};\n\tprivate onResetAll = () => {\n\t\tthis.resetAllData();\n\t};\n\n\tprivate get metadata() {\n\t\treturn this.metadataFamily.get(this.oid);\n\t}\n\n\tprivate get patchCreator() {\n\t\treturn this.ctx.patchCreator;\n\t}\n\n\t/**\n\t * The view of this Entity, not including nested\n\t * entities (that's the snapshot - see #getSnapshot())\n\t *\n\t * Nested entities are represented by refs.\n\t */\n\tprivate get viewData() {\n\t\tif (this._viewData === undefined) {\n\t\t\tthis._viewData = this.metadata.computeView();\n\t\t\tthis.validate();\n\t\t}\n\t\treturn this._viewData;\n\t}\n\n\t/** convenience getter for viewData.view */\n\tprivate get rawView() {\n\t\treturn this.viewData.view;\n\t}\n\n\t/**\n\t * An Entity's View includes the rendering of its underlying data,\n\t * connecting of children where refs were, and validation\n\t * and pruning according to schema.\n\t */\n\tprivate get view() {\n\t\tif (this.cachedView !== undefined) {\n\t\t\treturn this.cachedView;\n\t\t}\n\n\t\tif (this.viewData.deleted) {\n\t\t\treturn null;\n\t\t}\n\t\t// can't use invalid data - but this should be bubbled up to\n\t\t// a prune point\n\t\tconst rawView = this.rawView;\n\n\t\tconst viewIsWrongType =\n\t\t\t(!rawView && !isNullable(this.schema)) ||\n\t\t\t(this.schema.type === 'array' && !Array.isArray(rawView)) ||\n\t\t\t((this.schema.type === 'object' || this.schema.type === 'map') &&\n\t\t\t\t!isObject(rawView));\n\n\t\tif (viewIsWrongType) {\n\t\t\t// this will cover lists and maps, too.\n\t\t\tif (hasDefault(this.schema)) {\n\t\t\t\treturn getFieldDefault(this.schema);\n\t\t\t}\n\t\t\t// force null - invalid - will require parent prune\n\t\t\treturn null as any;\n\t\t}\n\n\t\tlet newView: any = this.isList ? [] : {};\n\t\tassignOid(newView, this.oid);\n\n\t\tif (Array.isArray(rawView)) {\n\t\t\tconst schema = getChildFieldSchema(this.schema, 0);\n\t\t\tif (!schema) {\n\t\t\t\t/**\n\t\t\t\t * PRUNE - this is a prune point. we can't continue\n\t\t\t\t * to render this data, so we'll just return [].\n\t\t\t\t * This skips the loop.\n\t\t\t\t */\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'error',\n\t\t\t\t\t'No child field schema for list entity.',\n\t\t\t\t\tthis.oid,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tfor (let i = 0; i < rawView.length; i++) {\n\t\t\t\t\tconst child = this.get(i);\n\t\t\t\t\tif (this.childIsNull(child) && !isNullable(schema)) {\n\t\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t\t'error',\n\t\t\t\t\t\t\t'Child missing in non-nullable field',\n\t\t\t\t\t\t\tthis.oid,\n\t\t\t\t\t\t\t'index:',\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// this item will be pruned.\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnewView.push(child);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (isObject(rawView)) {\n\t\t\t// iterate over known properties in object-type entities;\n\t\t\t// for maps, we just iterate over the keys.\n\t\t\tconst keys =\n\t\t\t\tthis.schema.type === 'object'\n\t\t\t\t\t? Object.keys(this.schema.properties)\n\t\t\t\t\t: Object.keys(rawView);\n\t\t\tfor (const key of keys) {\n\t\t\t\tconst schema = getChildFieldSchema(this.schema, key);\n\t\t\t\tif (!schema) {\n\t\t\t\t\t/**\n\t\t\t\t\t * PRUNE - this is a prune point. we can't continue\n\t\t\t\t\t * to render this data. If this is a map, it will be\n\t\t\t\t\t * pruned empty. Otherwise, prune moves upward.\n\t\t\t\t\t *\n\t\t\t\t\t * This exits the loop.\n\t\t\t\t\t */\n\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t'No child field schema for object entity at key',\n\t\t\t\t\t\tkey,\n\t\t\t\t\t);\n\t\t\t\t\tif (this.schema.type === 'map') {\n\t\t\t\t\t\t// it's valid to prune here if it's a map\n\t\t\t\t\t\tnewView = {};\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// otherwise prune moves upward\n\t\t\t\t\t\tnewView = null;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tconst child = this.get(key as any);\n\t\t\t\tif (this.childIsNull(child) && !isNullable(schema)) {\n\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t'Child entity is missing for non-nullable field',\n\t\t\t\t\t\tthis.oid,\n\t\t\t\t\t\t'key:',\n\t\t\t\t\t\tkey,\n\t\t\t\t\t);\n\t\t\t\t\tif (this.schema.type !== 'map') {\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * PRUNE - this is a prune point. we can't continue\n\t\t\t\t\t\t * to render this data. If this is a map, we can ignore\n\t\t\t\t\t\t * this value. Otherwise we must prune upward.\n\t\t\t\t\t\t * This exits the loop.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tnewView = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// special case - rewrite undefined fields to null\n\t\t\t\t\tif (isNullable(schema) && child === undefined) {\n\t\t\t\t\t\tnewView[key] = null;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnewView[key] = child;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.cachedView = newView;\n\t\treturn newView;\n\t}\n\n\tprivate childIsNull = (child: any) => {\n\t\tif (child instanceof Entity) {\n\t\t\tconst childView = child.view;\n\t\t\treturn childView === null || childView === undefined;\n\t\t}\n\t\treturn child === null || child === undefined;\n\t};\n\n\tget uid() {\n\t\treturn this.oid;\n\t}\n\n\tget deleted() {\n\t\treturn this.viewData.deleted || this.view === null;\n\t}\n\n\t/**\n\t * Doesn't compute view data; simply uses available cached\n\t * view info to determine deletion status.\n\t */\n\tprivate get quickDeleted() {\n\t\treturn this._viewData?.deleted || this.cachedView === null;\n\t}\n\n\tget invalid() {\n\t\treturn !!this.validate();\n\t}\n\n\t/**\n\t * Returns true if this or any child is invalid (pruned)\n\t */\n\tget deepInvalid(): boolean {\n\t\tif (this.invalid) return true;\n\t\tif (Array.isArray(this.rawView)) {\n\t\t\tfor (let i = 0; i < this.rawView.length; i++) {\n\t\t\t\tif (isObjectRef(this.rawView[i])) {\n\t\t\t\t\tconst child = this.getChild(i, this.rawView[i].id);\n\t\t\t\t\tif (child.deepInvalid) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (isObject(this.rawView)) {\n\t\t\tfor (const key in this.rawView) {\n\t\t\t\tif (isObjectRef(this.rawView[key])) {\n\t\t\t\t\tconst child = this.getChild(key, this.rawView[key].id);\n\t\t\t\t\tif (child.deepInvalid) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tget isList() {\n\t\t// have to turn TS off here as our two interfaces both implement\n\t\t// const values for this boolean.\n\t\treturn (\n\t\t\tthis.schema.type === 'array' || (Array.isArray(this.viewData.view) as any)\n\t\t);\n\t}\n\n\tget updatedAt() {\n\t\treturn this.viewData.updatedAt;\n\t}\n\n\tget deepUpdatedAt() {\n\t\tif (this.cachedDeepUpdatedAt) return this.cachedDeepUpdatedAt;\n\t\t// iterate over all children and take the latest timestamp\n\t\tlet latest: number | null = this.updatedAt;\n\t\tif (this.isList) {\n\t\t\tthis.forEach((child: any) => {\n\t\t\t\tif (child instanceof Entity) {\n\t\t\t\t\tconst childTimestamp = child.deepUpdatedAt;\n\t\t\t\t\tif (childTimestamp && (!latest || childTimestamp > latest)) {\n\t\t\t\t\t\tlatest = childTimestamp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tthis.values().forEach((child) => {\n\t\t\t\tif (child instanceof Entity) {\n\t\t\t\t\tconst childTimestamp = child.deepUpdatedAt;\n\t\t\t\t\tif (childTimestamp && (!latest || childTimestamp > latest)) {\n\t\t\t\t\t\tlatest = childTimestamp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tthis.cachedDeepUpdatedAt = latest;\n\t\treturn latest;\n\t}\n\n\t/**\n\t * @internal - this is relevant to Verdant's system, not users.\n\t *\n\t * Indicates whether this document is from an outdated version\n\t * of the schema - which means it cannot be used until it is upgraded.\n\t */\n\tget isOutdatedVersion(): boolean {\n\t\tif (this.parent) return this.parent.isOutdatedVersion;\n\t\treturn this.viewData.fromOlderVersion;\n\t}\n\n\t/**\n\t * Returns the storage namespace this entity came from. For example, if you\n\t * have multiple stores initialized from the same schema, you can use this\n\t * to figure out where an isolated entity was created / stored.\n\t */\n\tget namespace() {\n\t\treturn this.ctx.namespace;\n\t}\n\n\t/**\n\t * The authz string signifying the permissions this entity has.\n\t * On the client (where we are) it's only ever possible to see\n\t * an entity with either full access or access for the current\n\t * user.\n\t */\n\tget access() {\n\t\treturn this.viewData.authz;\n\t}\n\tget isAuthorized() {\n\t\treturn !!this.access;\n\t}\n\n\t/**\n\t * Introspects the schema of a child field of this entity.\n\t */\n\tgetFieldSchema = (key: any): StorageFieldSchema => {\n\t\tconst fieldSchema = getChildFieldSchema(this.schema, key);\n\t\tassert(fieldSchema, `No schema for key ${key}`);\n\t\treturn fieldSchema;\n\t};\n\n\t/**\n\t * Pruning - when entities have invalid children, we 'prune' that\n\t * data up to the nearest prunable point - a nullable field,\n\t * or a list.\n\t */\n\tprotected validate = memoByKeys(\n\t\t() => {\n\t\t\tthis.validationError =\n\t\t\t\tvalidateEntityField({\n\t\t\t\t\tfield: this.schema,\n\t\t\t\t\tvalue: this.rawView,\n\t\t\t\t\tfieldPath: this.fieldPath,\n\t\t\t\t\texpectRefs: true,\n\t\t\t\t}) ?? undefined;\n\t\t\treturn this.validationError;\n\t\t},\n\t\t() => [this.viewData],\n\t);\n\n\tprivate viewWithMappedChildren = (\n\t\tmapper: (child: Entity | EntityFile) => any,\n\t) => {\n\t\tconst view = this.view;\n\t\tif (!view) {\n\t\t\treturn null;\n\t\t}\n\t\tif (Array.isArray(view)) {\n\t\t\tconst mapped = view.map((value) => {\n\t\t\t\tif (value instanceof Entity || value instanceof EntityFile) {\n\t\t\t\t\treturn mapper(value);\n\t\t\t\t} else {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t});\n\t\t\tassignOid(mapped, this.oid);\n\t\t\treturn mapped;\n\t\t} else {\n\t\t\tconst mapped = Object.entries(view).reduce((acc, [key, value]) => {\n\t\t\t\tif (value instanceof Entity || value instanceof EntityFile) {\n\t\t\t\t\tacc[key as any] = mapper(value);\n\t\t\t\t} else {\n\t\t\t\t\tacc[key as any] = value;\n\t\t\t\t}\n\t\t\t\treturn acc;\n\t\t\t}, {} as any);\n\t\t\tassignOid(mapped, this.oid);\n\t\t\treturn mapped;\n\t\t}\n\t};\n\n\tprivate rawViewWithMappedChildren = (\n\t\tmapper: (child: Entity | EntityFile) => any,\n\t) => {\n\t\tconst view = this.rawView;\n\t\tif (!view) {\n\t\t\treturn null;\n\t\t}\n\t\tif (Array.isArray(view)) {\n\t\t\tconst mapped = view.map((value, i) => {\n\t\t\t\tif (isRef(value)) {\n\t\t\t\t\treturn mapper(this.getChild(i, value.id));\n\t\t\t\t} else {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t});\n\t\t\tassignOid(mapped, this.oid);\n\t\t\treturn mapped;\n\t\t} else {\n\t\t\tconst mapped = Object.entries(view).reduce((acc, [key, value]) => {\n\t\t\t\tif (isRef(value)) {\n\t\t\t\t\tacc[key as any] = mapper(this.getChild(key, value.id));\n\t\t\t\t} else {\n\t\t\t\t\tacc[key as any] = value;\n\t\t\t\t}\n\t\t\t\treturn acc;\n\t\t\t}, {} as any);\n\t\t\tassignOid(mapped, this.oid);\n\t\t\treturn mapped;\n\t\t}\n\t};\n\n\t/**\n\t * A current snapshot of this Entity's data, including nested\n\t * Entities.\n\t */\n\tgetSnapshot = (): any => {\n\t\treturn this.viewWithMappedChildren((child) => child.getSnapshot());\n\t};\n\n\t/**\n\t * A snapshot of this Entity with unpruned (invalid) data. This will\n\t * not conform to the entity schema and should be used carefully.\n\t *\n\t * Can be used to inspect or recover invalid, pruned data not\n\t * otherwise accessible.\n\t */\n\tgetUnprunedSnapshot = (): any => {\n\t\treturn this.rawViewWithMappedChildren((child) => {\n\t\t\tif (child instanceof EntityFile) return child.getSnapshot();\n\t\t\treturn child.getUnprunedSnapshot();\n\t\t});\n\t};\n\n\t// change management methods (internal use only)\n\tprivate addPendingOperations = (operations: Operation[]) => {\n\t\tthis.ctx.log(\n\t\t\t'debug',\n\t\t\t'Entity: adding pending operations',\n\t\t\tthis.oid,\n\t\t\toperations,\n\t\t);\n\n\t\t// special case -- if this entity is pruned, any changes we apply to it\n\t\t// will be in relation to 'exposed' pruned data, not the 'real world'\n\t\t// data that's backing it. That means those changes will produce unexpected\n\t\t// or further invalid results. To avoid this, we basically stamp in the\n\t\t// pruned version of this entity before proceeding.\n\t\t//\n\t\t// as an example of a failure mode without this check, consider a list:\n\t\t// [1, 2, <pruned>, 4, 5]\n\t\t// the user sees: [1, 2, 4, 5]\n\t\t// when they try to replace the item at index 2 with \"0\" (they see \"4\"), they\n\t\t// actually replace the invisible pruned item, resulting in [1, 2, 0, 4, 5]\n\t\t// being the result when they expected [1, 2, 0, 5].\n\t\t//\n\t\t// To \"stamp\" the data before applying user changes, we diff the snapshot\n\t\t// (which is the pruned version) with the current state of the entity.\n\t\tif (this.deepInvalid) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'warn',\n\t\t\t\t'Changes are being applied to a pruned entity. This means that the pruned version is being treated as the new baseline and any pruned invalid data is lost.',\n\t\t\t\tthis.oid,\n\t\t\t);\n\t\t\tthis.canonizePrunedVersion();\n\t\t}\n\n\t\tthis.applyPendingOperations(operations);\n\t};\n\n\t// naming is fuzzy here, but this method was split out from\n\t// addPendingOperations since that method also conditionally canonizes\n\t// the pruned snapshot, and I wanted to keep the actual insertion of\n\t// the ops in one place, so leaving it as part of addPendingOperations\n\t// would introduce infinite recursion when canonizing.\n\tprivate applyPendingOperations = (operations: Operation[]) => {\n\t\t// apply authz to all operations\n\t\tif (this.access) {\n\t\t\tfor (const op of operations) {\n\t\t\t\top.authz = this.access;\n\t\t\t}\n\t\t}\n\n\t\tconst changes = this.metadataFamily.addPendingData(operations);\n\t\tfor (const change of changes) {\n\t\t\tthis.change(change);\n\t\t}\n\t};\n\n\tprivate getPruneDiff = () => {\n\t\tconst snapshot = this.getSnapshot();\n\t\tconst unprunedSnapshot = this.getUnprunedSnapshot();\n\t\treturn this.patchCreator.createDiff(unprunedSnapshot, snapshot, {\n\t\t\tauthz: this.access,\n\t\t\tmerge: false,\n\t\t});\n\t};\n\tprivate canonizePrunedVersion = () => {\n\t\tthis.applyPendingOperations(this.getPruneDiff());\n\t};\n\n\tprivate addConfirmedData = (data: EntityStoreEventData) => {\n\t\tthis.ctx.log('debug', 'Entity: adding confirmed data', this.oid);\n\t\tconst changes = this.metadataFamily.addConfirmedData(data);\n\t\tfor (const change of changes) {\n\t\t\tthis.change(change);\n\t\t}\n\t};\n\n\tprivate replaceAllData = (data: EntityStoreEventData) => {\n\t\tthis.ctx.log('debug', 'Entity: replacing all data', this.oid);\n\t\tconst changes = this.metadataFamily.replaceAllData(data);\n\t\tfor (const change of changes) {\n\t\t\tthis.change(change);\n\t\t}\n\t};\n\n\tprivate resetAllData = () => {\n\t\tthis.ctx.log('debug', 'Entity: resetting all data', this.oid);\n\t\tthis.cachedDeepUpdatedAt = null;\n\t\tthis.cachedView = undefined;\n\t\tthis._viewData = undefined;\n\t\tconst changes = this.metadataFamily.replaceAllData({});\n\t\tfor (const change of changes) {\n\t\t\tthis.change(change);\n\t\t}\n\t};\n\n\tprivate invalidateCachedView = () => {\n\t\tthis._viewData = undefined;\n\t\tthis.cachedView = undefined;\n\t};\n\n\t// invalidates cached view of any entity targetted by change. this can\n\t// be called by any member of the tree and will automatically target\n\t// the correct entity.\n\tprivate invalidate = (ev: EntityChange) => {\n\t\tif (ev.oid === this.oid) {\n\t\t\tthis.invalidateCachedView();\n\t\t} else {\n\t\t\tconst other = this.entityFamily.getCached(ev.oid);\n\t\t\tif (other && other instanceof Entity) {\n\t\t\t\t// forward the invalidation to the correct family member.\n\t\t\t\tother.invalidate(ev);\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate change = (ev: EntityChange) => {\n\t\tif (ev.oid === this.oid) {\n\t\t\t// reset cached view\n\t\t\tthis.invalidateCachedView();\n\t\t\tif (!this.parent) {\n\t\t\t\tthis.changeRoot(ev);\n\t\t\t} else {\n\t\t\t\tthis.changeNested(ev);\n\t\t\t}\n\t\t} else {\n\t\t\t// forward it to the correct family member. if none exists\n\t\t\t// in cache, no one will hear it anyways.\n\t\t\tconst other = this.entityFamily.getCached(ev.oid);\n\t\t\tif (other && other instanceof Entity) {\n\t\t\t\tother.change(ev);\n\t\t\t}\n\t\t}\n\t};\n\tprivate changeRoot = (ev: EntityChange) => {\n\t\t// for root entities, we need to determine if we're deleted or not\n\t\t// before firing any events\n\t\tif (this.deleted) {\n\t\t\tif (!this.wasDeletedLastChange) {\n\t\t\t\tthis.ctx.log('debug', 'Entity deleted', this.oid);\n\t\t\t\tthis.emit('delete', { isLocal: ev.isLocal });\n\t\t\t\tthis.wasDeletedLastChange = true;\n\t\t\t} else {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'Entity already deleted, not emitting delete or change events',\n\t\t\t\t\tthis.oid,\n\t\t\t\t);\n\t\t\t\t// already deleted, do nothing.\n\t\t\t}\n\t\t} else {\n\t\t\tif (this.wasDeletedLastChange) {\n\t\t\t\tthis.ctx.log('debug', 'Entity restored', this.oid);\n\t\t\t\tthis.emit('restore', { isLocal: ev.isLocal });\n\t\t\t\tthis.wasDeletedLastChange = false;\n\t\t\t}\n\t\t\t// emit deepchange, too\n\t\t\tthis.deepChange(this, ev);\n\t\t\t// emit the change, it's for us\n\t\t\tthis.emit('change', { isLocal: ev.isLocal });\n\t\t}\n\t};\n\tprivate changeNested = (ev: EntityChange) => {\n\t\t// do not emit changes when deleted\n\t\tif (this.deleted) {\n\t\t\tthis.ctx.log('debug', 'Entity deleted, not emitting change', this.oid);\n\t\t\treturn;\n\t\t}\n\t\t// chain deepChanges to parents\n\t\tthis.deepChange(this, ev);\n\t\t// emit the change, it's for us\n\t\tthis.emit('change', { isLocal: ev.isLocal });\n\t};\n\tprotected deepChange = (target: Entity, ev: EntityChange) => {\n\t\tif (this.deleted) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'debug',\n\t\t\t\t'Entity deleted, not emitting deep change',\n\t\t\t\tthis.oid,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\t// reset cached deep updated at timestamp; either this\n\t\t// entity or children have changed\n\t\tthis.cachedDeepUpdatedAt = null;\n\t\t// reset this flag to recompute snapshot data - children\n\t\t// or self has changed. new pruning needs to happen.\n\t\tthis.cachedView = undefined;\n\t\tthis.emit('changeDeep', target, ev);\n\t\tthis.parent?.deepChange(target, ev);\n\t};\n\t[CHILD_FILE_CHANGED] = (file: EntityFile) => {\n\t\t// consistent with prior behavior, but kind of arbitrary.\n\t\tthis.deepChange(this, { isLocal: false, oid: this.oid });\n\t};\n\n\tprivate getChild = (key: any, oid: ObjectIdentifier) => {\n\t\tconst schema = getChildFieldSchema(this.schema, key);\n\t\tif (!schema) {\n\t\t\tthrow new Error(\n\t\t\t\t`No schema for key ${String(key)} in ${JSON.stringify(this.schema)}`,\n\t\t\t);\n\t\t}\n\t\treturn this.entityFamily.get({\n\t\t\toid,\n\t\t\tschema,\n\t\t\tentityFamily: this.entityFamily,\n\t\t\tmetadataFamily: this.metadataFamily,\n\t\t\tparent: this,\n\t\t\tctx: this.ctx,\n\t\t\tfiles: this.files,\n\t\t\tfieldPath: [...this.fieldPath, key],\n\t\t\tstoreEvents: this.storeEvents,\n\t\t\tdeleteSelf: this.delete.bind(this, key),\n\t\t});\n\t};\n\n\tsubscribeToField = <K extends keyof KeyValue>(\n\t\tkey: K,\n\t\tevent: 'change', // here to keep future api changes stable\n\t\tcallback: (\n\t\t\tvalue: KeyValue[K],\n\t\t\tinfo: { previousValue: KeyValue[K]; isLocal?: boolean },\n\t\t) => void,\n\t) => {\n\t\treturn entityFieldSubscriber<KeyValue[K]>(this, key, callback);\n\t};\n\n\t// generic entity methods\n\t/**\n\t * Gets a value from this Entity. If the value\n\t * is an object, it will be wrapped in another\n\t * Entity.\n\t */\n\tget = <Key extends keyof KeyValue>(key: Key): KeyValue[Key] => {\n\t\tassertNotSymbol(key);\n\n\t\tconst view = this.rawView;\n\t\tif (!view) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot access data at key ${key} on deleted entity ${this.oid}`,\n\t\t\t);\n\t\t}\n\t\tconst child = view[key as any];\n\t\tconst fieldSchema = getChildFieldSchema(this.schema, key);\n\t\tif (!fieldSchema) {\n\t\t\tthrow new Error(\n\t\t\t\t`No schema for key ${String(key)} in ${JSON.stringify(this.schema)}`,\n\t\t\t);\n\t\t}\n\t\tif (isRef(child)) {\n\t\t\tif (isFileRef(child)) {\n\t\t\t\tif (fieldSchema.type !== 'file') {\n\t\t\t\t\t// at least try to not fail\n\t\t\t\t\tif (isNullable(fieldSchema)) {\n\t\t\t\t\t\treturn null as KeyValue[Key];\n\t\t\t\t\t} else if (hasDefault(fieldSchema)) {\n\t\t\t\t\t\treturn getFieldDefault(fieldSchema) as KeyValue[Key];\n\t\t\t\t\t}\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Expected file schema for key ${String(key)}, got ${\n\t\t\t\t\t\t\tfieldSchema.type\n\t\t\t\t\t\t}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst file = this.files.get(child.id, {\n\t\t\t\t\tdownloadRemote: !!fieldSchema.downloadRemote,\n\t\t\t\t\tctx: this.ctx,\n\t\t\t\t\tparent: this,\n\t\t\t\t});\n\n\t\t\t\treturn file as KeyValue[Key];\n\t\t\t} else {\n\t\t\t\tif (fieldSchema.type === 'file') {\n\t\t\t\t\t// schema and child ref type do not match...\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`Expected file ref for key ${String(key)}, got ${child}`,\n\t\t\t\t\t);\n\t\t\t\t\t// at least try to not fail\n\t\t\t\t\tif (isNullable(fieldSchema)) {\n\t\t\t\t\t\treturn null as KeyValue[Key];\n\t\t\t\t\t} else if (hasDefault(fieldSchema)) {\n\t\t\t\t\t\treturn getFieldDefault(fieldSchema) as KeyValue[Key];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`No valid value for key ${String(key)} in ${JSON.stringify(this.schema)}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst childEntity = this.getChild(key, child.id);\n\t\t\t\tif (childEntity.deepInvalid) {\n\t\t\t\t\t// this child is pruned. materialize a pruned version of\n\t\t\t\t\t// this subtree if possible.\n\n\t\t\t\t\t// special case: lists -- as long as the list itself\n\t\t\t\t\t// is present and valid, it can omit invalid children\n\t\t\t\t\t// selectively rather than fallback to an empty default\n\t\t\t\t\tif (fieldSchema.type === 'array') {\n\t\t\t\t\t\treturn childEntity as KeyValue[Key];\n\t\t\t\t\t}\n\t\t\t\t\t// special case: maps -- similar to lists\n\t\t\t\t\tif (fieldSchema.type === 'map') {\n\t\t\t\t\t\treturn childEntity as KeyValue[Key];\n\t\t\t\t\t}\n\t\t\t\t\tif (isNullable(fieldSchema)) {\n\t\t\t\t\t\treturn null as KeyValue[Key];\n\t\t\t\t\t}\n\t\t\t\t\tif (hasDefault(fieldSchema)) {\n\t\t\t\t\t\tconst unprunedSnapshot = childEntity.getUnprunedSnapshot();\n\t\t\t\t\t\tconst pruneDiff = this.patchCreator.createDiff(\n\t\t\t\t\t\t\tunprunedSnapshot,\n\t\t\t\t\t\t\tgetFieldDefault(fieldSchema),\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmerge: false,\n\t\t\t\t\t\t\t\tmergeUnknownObjects: true,\n\t\t\t\t\t\t\t\tauthz: this.access,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn this.processPrunedChild(key, childEntity, pruneDiff);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn childEntity as KeyValue[Key];\n\t\t\t}\n\t\t} else {\n\t\t\t// if this is a Map type, a missing child is\n\t\t\t// just an empty spot\n\t\t\tif (this.schema.type === 'map' && child === undefined) {\n\t\t\t\treturn undefined as KeyValue[Key];\n\t\t\t}\n\t\t\t// prune invalid primitive fields\n\t\t\tif (\n\t\t\t\tvalidateEntityField({\n\t\t\t\t\tfield: fieldSchema,\n\t\t\t\t\tvalue: child,\n\t\t\t\t\tfieldPath: [...this.fieldPath, key],\n\t\t\t\t\tdepth: 1,\n\t\t\t\t\trequireDefaults: true,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tif (hasDefault(fieldSchema)) {\n\t\t\t\t\t// primitive fields with defaults are easy.\n\t\t\t\t\tif (isPrimitive(fieldSchema)) {\n\t\t\t\t\t\treturn getFieldDefault(fieldSchema) as KeyValue[Key];\n\t\t\t\t\t}\n\n\t\t\t\t\t// object/list fields are hard.\n\t\t\t\t\tconst defaultValue = getFieldDefault(fieldSchema);\n\t\t\t\t\tconst prunedFieldOid = createSubOid(this.oid);\n\t\t\t\t\tconst pruneDiff = this.patchCreator.createInitialize(\n\t\t\t\t\t\tdefaultValue,\n\t\t\t\t\t\tprunedFieldOid,\n\t\t\t\t\t\tthis.access,\n\t\t\t\t\t);\n\t\t\t\t\tpruneDiff.push(\n\t\t\t\t\t\t...this.patchCreator.createSet(\n\t\t\t\t\t\t\tthis.oid,\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\tcreateRef(prunedFieldOid),\n\t\t\t\t\t\t\tthis.access,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t\tconst childEntity = this.getChild(key, prunedFieldOid);\n\t\t\t\t\treturn this.processPrunedChild(key, childEntity, pruneDiff);\n\t\t\t\t} else {\n\t\t\t\t\t// failure / hard prune: no way to represent this\n\t\t\t\t\t// data in a valid way exists. the parent entity\n\t\t\t\t\t// is also invalid and this should bubble up.\n\t\t\t\t\treturn undefined as KeyValue[Key];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn child as KeyValue[Key];\n\t\t}\n\t};\n\n\tprivate processPrunedChild = (\n\t\tkey: any,\n\t\tchild: Entity,\n\t\tpruneDiff: Operation[],\n\t): any => {\n\t\tthis.ctx.log(\n\t\t\t'warn',\n\t\t\t'Replacing invalid child object field with ephemeral, valid data',\n\t\t\tthis.oid,\n\t\t\tkey,\n\t\t);\n\t\tconst changes = this.metadataFamily.addEphemeralData(pruneDiff);\n\t\tfor (const change of changes) {\n\t\t\tthis.invalidate(change);\n\t\t}\n\t\treturn child as any;\n\t};\n\n\t/**\n\t * Gets a value on this entity. If the value is not\n\t * present, it will be set to the provided default\n\t * and returned synchronously. This method only sets\n\t * a new value once when a field is empty; subsequent\n\t * calls will retrieve the created value until it is\n\t * deleted.\n\t *\n\t * Note that this should only be called for nullable\n\t * fields. If the field is not nullable, the existing\n\t * value or the default value will always be returned,\n\t * and the default will not be set.\n\t */\n\tgetOrSet = <Key extends keyof Init & keyof KeyValue>(\n\t\tkey: Key,\n\t\tinit: Init[Key],\n\t): KeyValue[Key] => {\n\t\tassertNotSymbol(key);\n\t\tconst existing = this.get(key);\n\t\tif (existing) return existing;\n\t\tthis.set(key as any, init);\n\t\treturn this.get(key);\n\t};\n\n\tprivate processInputValue = (value: any, key: any) => {\n\t\tif (this.readonlyKeys.includes(key as string)) {\n\t\t\tthrow new Error(`Cannot set readonly key ${key.toString()}`);\n\t\t}\n\t\t// disassociate incoming OIDs on values and generally break object\n\t\t// references. cloning doesn't work on files so those are\n\t\t// filtered out.\n\t\t// The goal here is to be safe about a bunch of cases that could\n\t\t// result in corrupt data, like...\n\t\t// ent1.set('objField', ent2.get('objField'))\n\t\t// or\n\t\t// var shared = { foo: 'bar' };\n\t\t// ent1.set('objField', shared);\n\t\t// ent2.set('objField', shared);\n\t\t// ... each of these would result in the same object being\n\t\t// referenced in multiple entities, which could mean introduction\n\t\t// of foreign OIDs, or one object being assigned different OIDs\n\t\t// with unexpected results.\n\t\tif (!isFile(value)) {\n\t\t\tvalue = cloneDeep(value, false);\n\t\t}\n\t\tconst fieldSchema = getChildFieldSchema(this.schema, key);\n\t\tif (fieldSchema) {\n\t\t\ttraverseCollectionFieldsAndApplyDefaults(value, fieldSchema);\n\t\t\tconst validationError = validateEntityField({\n\t\t\t\tfield: fieldSchema,\n\t\t\t\tvalue,\n\t\t\t\tfieldPath: [...this.fieldPath, key],\n\t\t\t});\n\t\t\tif (validationError) {\n\t\t\t\t// TODO: is it a good idea to throw an error here? a runtime error won't be that helpful,\n\t\t\t\t// but also we don't really want invalid data supplied.\n\t\t\t\tthrow new Error(`Validation error: ${validationError.message}`, {\n\t\t\t\t\tcause: validationError,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn processValueFiles(value, (file) => this.files.add(file, this));\n\t};\n\n\tprivate getDeleteMode = (key: any) => {\n\t\tif (this.readonlyKeys.includes(key)) {\n\t\t\treturn false;\n\t\t}\n\t\t// any is always deletable, and map values\n\t\tif (this.schema.type === 'any' || this.schema.type === 'map') {\n\t\t\treturn 'delete';\n\t\t}\n\n\t\tif (this.schema.type === 'object') {\n\t\t\tconst property = this.schema.properties[key];\n\t\t\tif (!property) {\n\t\t\t\t// huh, the property doesn't exist. it's ok to\n\t\t\t\t// remove I suppose.\n\t\t\t\treturn 'delete';\n\t\t\t}\n\t\t\tif (property.type === 'any') return 'delete';\n\t\t\t// map can't be nullable. should it be?\n\t\t\tif (property.type === 'map') return false;\n\t\t\tif (property.nullable) return 'null';\n\t\t}\n\t\t// no other types are deletable\n\t\treturn false;\n\t};\n\n\t/**\n\t * Returns the referent value of an item in the list, used for\n\t * operations which act on items. if the item is an object,\n\t * it will attempt to create an OID reference to it. If it\n\t * is a primitive, it will return the primitive.\n\t */\n\tprivate getItemRefValue = (item: any) => {\n\t\tif (item instanceof Entity) {\n\t\t\treturn createRef(item.oid);\n\t\t}\n\t\tif (item instanceof EntityFile) {\n\t\t\treturn createFileRef(item.id);\n\t\t}\n\t\tif (typeof item === 'object') {\n\t\t\tconst itemOid = maybeGetOid(item);\n\t\t\tif (!itemOid || !this.entityFamily.has(itemOid)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot move object ${JSON.stringify(\n\t\t\t\t\t\titem,\n\t\t\t\t\t)} which does not exist in this list`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn createRef(itemOid);\n\t\t} else {\n\t\t\treturn item;\n\t\t}\n\t};\n\n\tset = (\n\t\tkey: any,\n\t\tvalue: any,\n\t\toptions?: {\n\t\t\t/**\n\t\t\t * Forces the creation of a change for this set even if the value is the same\n\t\t\t * as the current value for this key. This has an effect in situations where\n\t\t\t * offline changes from others are interleaved with local changes; when setting\n\t\t\t * a value to its current value (force=true), if that value were retroactively changed from\n\t\t\t * offline changes, the set would put it back to the value specified. If the\n\t\t\t * set is ignored because the value is the same (force=false), then retroactive\n\t\t\t * changes will be preserved.\n\t\t\t */\n\t\t\tforce: boolean;\n\t\t},\n\t) => {\n\t\tassertNotSymbol(key);\n\t\tif (!options?.force && this.get(key) === value) return;\n\n\t\tif (this.isList) {\n\t\t\tthis.addPendingOperations(\n\t\t\t\tthis.patchCreator.createListSet(\n\t\t\t\t\tthis.oid,\n\t\t\t\t\tkey,\n\t\t\t\t\tthis.processInputValue(value, key),\n\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.addPendingOperations(\n\t\t\t\tthis.patchCreator.createSet(\n\t\t\t\t\tthis.oid,\n\t\t\t\t\tkey,\n\t\t\t\t\tthis.processInputValue(value, key),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t};\n\n\t/**\n\t * Returns a destructured version of this Entity, where child\n\t * Entities are accessible at their respective keys.\n\t */\n\tgetAll = (): KeyValue => {\n\t\treturn this.view;\n\t};\n\n\tdelete = (key: any) => {\n\t\tif (this.isList) {\n\t\t\tassertNumber(key);\n\t\t\tthis.addPendingOperations(\n\t\t\t\tthis.patchCreator.createListDelete(this.oid, key),\n\t\t\t);\n\t\t} else {\n\t\t\t// the key must be deletable - i.e. optional in the schema.\n\t\t\tconst deleteMode = this.getDeleteMode(key);\n\t\t\tif (!deleteMode) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot delete key ${key.toString()} - the property is not marked as optional in the schema.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (deleteMode === 'delete') {\n\t\t\t\tthis.addPendingOperations(\n\t\t\t\t\tthis.patchCreator.createRemove(this.oid, key),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.addPendingOperations(\n\t\t\t\t\tthis.patchCreator.createSet(this.oid, key, null),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t};\n\n\t// object entity methods\n\tkeys = (): string[] => {\n\t\tif (!this.view) return [];\n\t\treturn Object.keys(this.view);\n\t};\n\n\tentries = (): [string, Exclude<KeyValue[keyof KeyValue], undefined>][] => {\n\t\tif (!this.view) return [];\n\t\treturn Object.entries(this.view);\n\t};\n\n\tvalues = (): Exclude<KeyValue[keyof KeyValue], undefined>[] => {\n\t\tif (!this.view) return [];\n\t\treturn Object.values(this.view);\n\t};\n\n\tget size() {\n\t\tif (this.isList) {\n\t\t\treturn this.length;\n\t\t}\n\t\treturn this.keys().length;\n\t}\n\n\tupdate = (\n\t\tdata: any,\n\t\t{\n\t\t\tmerge = true,\n\t\t\treplaceSubObjects = false,\n\t\t\tpreserveUndefined = false,\n\t\t\tdangerouslyDisableMerge = false,\n\t\t}: {\n\t\t\treplaceSubObjects?: boolean;\n\t\t\tmerge?: boolean;\n\t\t\tpreserveUndefined?: boolean;\n\t\t\tdangerouslyDisableMerge?: boolean;\n\t\t} = {},\n\t): void => {\n\t\tif (\n\t\t\t!merge &&\n\t\t\t!dangerouslyDisableMerge &&\n\t\t\tthis.schema.type !== 'any' &&\n\t\t\tthis.schema.type !== 'map'\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t'Cannot use .update without merge if the field has a strict schema type. merge: false is only available on \"any\" or \"map\" types.',\n\t\t\t);\n\t\t}\n\t\tconst changes: any = {};\n\t\tassignOid(changes, this.oid);\n\t\tfor (const [key, field] of Object.entries(data)) {\n\t\t\tif (this.readonlyKeys.includes(key as any)) {\n\t\t\t\tthrow new Error(`Cannot set readonly key ${key.toString()}`);\n\t\t\t}\n\t\t\t// ignore undefined values unless overridden\n\t\t\tif (field === undefined && !preserveUndefined) continue;\n\n\t\t\tconst fieldSchema = getChildFieldSchema(this.schema, key);\n\t\t\tif (fieldSchema) {\n\t\t\t\ttraverseCollectionFieldsAndApplyDefaults(field, fieldSchema);\n\t\t\t}\n\t\t\tchanges[key] = this.processInputValue(field, key);\n\t\t}\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createDiff(this.getSnapshot(), changes, {\n\t\t\t\tmergeUnknownObjects: !replaceSubObjects,\n\t\t\t\tmerge,\n\t\t\t}),\n\t\t);\n\t};\n\n\t// array entity methods\n\tget length(): number {\n\t\treturn this.view.length;\n\t}\n\n\tpush = (value: ListItemInit<Init>): void => {\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createListPush(\n\t\t\t\tthis.oid,\n\t\t\t\tthis.processInputValue(value, this.view.length),\n\t\t\t),\n\t\t);\n\t};\n\n\tinsert = (index: number, value: ListItemInit<Init>): void => {\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createListInsert(\n\t\t\t\tthis.oid,\n\t\t\t\tindex,\n\t\t\t\tthis.processInputValue(value, index),\n\t\t\t),\n\t\t);\n\t};\n\n\tmove = (from: number, to: number): void => {\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createListMoveByIndex(this.oid, from, to),\n\t\t);\n\t};\n\n\tmoveItem = (item: ListItemValue<KeyValue>, to: number): void => {\n\t\tconst itemRef = this.getItemRefValue(item);\n\t\tif (isRef(itemRef)) {\n\t\t\tthis.addPendingOperations(\n\t\t\t\tthis.patchCreator.createListMoveByRef(this.oid, itemRef, to),\n\t\t\t);\n\t\t} else {\n\t\t\tconst index = this.view.indexOf(item);\n\t\t\tif (index === -1) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot move item ${JSON.stringify(\n\t\t\t\t\t\titem,\n\t\t\t\t\t)} which does not exist in this list`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.move(index, to);\n\t\t}\n\t};\n\n\tadd = (value: ListItemValue<KeyValue>): void => {\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createListAdd(\n\t\t\t\tthis.oid,\n\t\t\t\tthis.processInputValue(value, this.view.length),\n\t\t\t),\n\t\t);\n\t};\n\n\tremoveAll = (item: ListItemValue<KeyValue>): void => {\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createListRemove(this.oid, this.getItemRefValue(item)),\n\t\t);\n\t};\n\n\tremoveFirst = (item: ListItemValue<KeyValue>): void => {\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createListRemove(\n\t\t\t\tthis.oid,\n\t\t\t\tthis.getItemRefValue(item),\n\t\t\t\t'first',\n\t\t\t),\n\t\t);\n\t};\n\n\tremoveLast = (item: ListItemValue<KeyValue>): void => {\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createListRemove(\n\t\t\t\tthis.oid,\n\t\t\t\tthis.getItemRefValue(item),\n\t\t\t\t'last',\n\t\t\t),\n\t\t);\n\t};\n\n\t// list implements an iterator which maps items to wrapped\n\t// versions\n\t[Symbol.iterator]() {\n\t\tlet index = 0;\n\t\tlet length = this.view?.length;\n\t\treturn {\n\t\t\tnext: () => {\n\t\t\t\tif (index < length) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tvalue: this.get(index++) as ListItemValue<KeyValue>,\n\t\t\t\t\t\tdone: false,\n\t\t\t\t\t} as const;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tvalue: undefined,\n\t\t\t\t\tdone: true,\n\t\t\t\t} as const;\n\t\t\t},\n\t\t};\n\t}\n\n\tmap = <U>(\n\t\tcallback: (value: ListItemValue<KeyValue>, index: number) => U,\n\t): U[] => {\n\t\treturn this.view.map(callback);\n\t};\n\n\tfilter = (\n\t\tcallback: (value: ListItemValue<KeyValue>, index: number) => boolean,\n\t): ListItemValue<KeyValue>[] => {\n\t\treturn this.view.filter(callback);\n\t};\n\n\thas = (value: ListItemValue<KeyValue>): boolean => {\n\t\tif (!this.isList) {\n\t\t\tthrow new Error('has() is only available on list entities');\n\t\t}\n\t\tconst itemRef = this.getItemRefValue(value);\n\t\tif (isRef(itemRef)) {\n\t\t\treturn this.view.some((item: any) => {\n\t\t\t\tif (isRef(item)) {\n\t\t\t\t\treturn compareRefs(item, itemRef);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\treturn this.view.includes(value);\n\t\t}\n\t};\n\n\tforEach = (\n\t\tcallback: (value: ListItemValue<KeyValue>, index: number) => void,\n\t): void => {\n\t\tthis.view.forEach(callback);\n\t};\n\n\treduce = <U>(\n\t\tcallback: (\n\t\t\tpreviousValue: U,\n\t\t\tcurrentValue: ListItemValue<KeyValue>,\n\t\t\tindex: number,\n\t\t) => U,\n\t\tinitialValue: U,\n\t): U => {\n\t\treturn this.view.reduce(callback, initialValue);\n\t};\n\n\tsome = (predicate: (value: ListItemValue<KeyValue>) => boolean): boolean => {\n\t\treturn this.view.some(predicate);\n\t};\n\n\tevery = (predicate: (value: ListItemValue<KeyValue>) => boolean): boolean => {\n\t\treturn this.view.every(predicate);\n\t};\n\n\tfind = (\n\t\tpredicate: (value: ListItemValue<KeyValue>) => boolean,\n\t): ListItemValue<KeyValue> | undefined => {\n\t\treturn this.view.find(predicate);\n\t};\n\n\tincludes = this.has;\n\n\t/**\n\t * Deletes this entity. WARNING: this can be tricky to\n\t * use correctly. You must not reference this entity\n\t * instance in any way after the deletion happens, or\n\t * you will get an error!\n\t *\n\t * It's a little easier to delete using client.delete\n\t * if you can manage it with your app's code. For example,\n\t * in React, use hooks.useClient() to get the client and\n\t * call delete from there.\n\t */\n\tdeleteSelf = () => {\n\t\treturn this._deleteSelf();\n\t};\n\n\t// TODO: make these escape hatches unnecessary\n\t__getViewData__ = (oid: ObjectIdentifier, type: 'confirmed' | 'pending') => {\n\t\treturn this.metadataFamily.get(oid).computeView(type === 'confirmed');\n\t};\n\t__getFamilyOids__ = () => this.metadataFamily.getAllOids();\n\n\t__discardPendingOperation__ = (operation: Operation) => {\n\t\tthis.metadataFamily.discardPendingOperation(operation);\n\t\tthis.invalidateCachedView();\n\t};\n}\n\nfunction assertNotSymbol<T>(key: T): asserts key is Exclude<T, symbol> {\n\tif (typeof key === 'symbol') throw new Error(\"Symbol keys aren't supported\");\n}\n\nfunction assertNumber(key: unknown): asserts key is number {\n\tif (typeof key !== 'number')\n\t\tthrow new Error('Only number keys are supported in list entities');\n}\n\nexport function getEntityClient(\n\tentity: AnyEntity<any, any, any>,\n): ClientWithCollections {\n\treturn (entity as Entity)[\n\t\tPRIVATE_ENTITY_CONTEXT_KEY\n\t].getClient() as ClientWithCollections;\n}\n", "import {\n\tAuthorizationKey,\n\tDocumentBaseline,\n\tObjectIdentifier,\n\tOperation,\n\tapplyPatch,\n\tareOidsRelated,\n\tassert,\n\tassignOid,\n\tcloneDeep,\n\tcompareTimestampSchemaVersions,\n\tgetWallClockTime,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { EntityChange } from './types.js';\n\nexport type EntityMetadataView = {\n\tview: any;\n\tfromOlderVersion: boolean;\n\tdeleted: boolean;\n\tempty: boolean;\n\tupdatedAt: number;\n\tlatestTimestamp: string | null;\n\tauthz?: AuthorizationKey;\n};\n\nexport class EntityMetadata {\n\tprivate ctx;\n\tprivate baseline: DocumentBaseline | null = null;\n\t// these must be kept in timestamp order.\n\tprivate confirmedOperations: Operation[] = [];\n\t// operations applied locally, but not sent to persistence\n\t// until 'committed' by pending operations. this powers the\n\t// self-healing pruning system, which injects these ephemeral\n\t// operations to materialize pruned 'fixed' data in place of\n\t// 'real' invalid data so the user can keep using the app. as\n\t// soon as the user makes modifications to the entity, this\n\t// ephemeral pruned data is applied underneath it.\n\tprivate ephemeralOperations?: Operation[] = [];\n\tprivate pendingOperations: Operation[] = [];\n\treadonly oid;\n\n\tconstructor({\n\t\toid,\n\t\tctx,\n\t\tconfirmedOperations,\n\t\tpendingOperations,\n\t\tbaseline,\n\t}: {\n\t\toid: ObjectIdentifier;\n\t\tctx: Context;\n\t\tconfirmedOperations?: Operation[];\n\t\tpendingOperations?: Operation[];\n\t\tbaseline?: DocumentBaseline;\n\t}) {\n\t\tassert(oid, 'oid is required');\n\t\tthis.ctx = ctx;\n\t\tthis.oid = oid;\n\t\tif (confirmedOperations) {\n\t\t\tthis.confirmedOperations = confirmedOperations;\n\t\t}\n\t\tif (pendingOperations) {\n\t\t\tthis.pendingOperations = pendingOperations;\n\t\t}\n\t\tif (baseline) {\n\t\t\tthis.baseline = baseline;\n\t\t}\n\t}\n\n\t/**\n\t * Compute the current view of the entity.\n\t */\n\tcomputeView = (omitPending = false): EntityMetadataView => {\n\t\tconst base = cloneDeep(this.baseline?.snapshot ?? undefined);\n\t\tconst baselineTimestamp = this.baseline?.timestamp ?? null;\n\n\t\t// start with the baseline authz, if any. further init ops\n\t\t// may overwrite this.\n\t\tlet authz = this.baseline?.authz;\n\n\t\tconst confirmedResult = this.applyOperations(\n\t\t\t// apply ops to baseline\n\t\t\tbase,\n\t\t\t// deleted if there's no baseline\n\t\t\t!base,\n\t\t\t// we're applying confirmed ops first\n\t\t\tthis.confirmedOperations,\n\t\t\t// latest timestamp is the baseline timestamp, if any\n\t\t\tbaselineTimestamp,\n\t\t\t// only apply ops after the baseline timestamp\n\t\t\tbaselineTimestamp,\n\t\t);\n\t\t// now's the time to declare we saw the future if we did.\n\t\tif (confirmedResult.futureSeen) {\n\t\t\tthis.ctx.globalEvents.emit('futureSeen', confirmedResult.futureSeen);\n\t\t}\n\t\tif (confirmedResult.authz) {\n\t\t\tauthz = confirmedResult.authz;\n\t\t}\n\n\t\tconst ephemeralResult =\n\t\t\t!this.ephemeralOperations || omitPending\n\t\t\t\t? confirmedResult\n\t\t\t\t: this.applyOperations(\n\t\t\t\t\t\tconfirmedResult.view,\n\t\t\t\t\t\tconfirmedResult.deleted,\n\t\t\t\t\t\tthis.ephemeralOperations,\n\t\t\t\t\t\tconfirmedResult.latestTimestamp,\n\t\t\t\t\t\tnull,\n\t\t\t\t\t);\n\n\t\tconst pendingResult = omitPending\n\t\t\t? confirmedResult\n\t\t\t: this.applyOperations(\n\t\t\t\t\tephemeralResult.view,\n\t\t\t\t\tephemeralResult.deleted,\n\t\t\t\t\t// now we're applying pending operations\n\t\t\t\t\tthis.pendingOperations,\n\t\t\t\t\t// keep our latest timestamp up to date\n\t\t\t\t\tephemeralResult.latestTimestamp,\n\t\t\t\t\t// we don't use after for pending ops, they're all\n\t\t\t\t\t// logically in the future\n\t\t\t\t\tnull,\n\t\t\t\t);\n\t\tif (pendingResult.authz) {\n\t\t\tauthz = pendingResult.authz;\n\t\t}\n\n\t\t// before letting this data out into the wild, we need\n\t\t// to associate its oid\n\t\tif (pendingResult.view) {\n\t\t\tassignOid(pendingResult.view, this.oid);\n\t\t}\n\n\t\t// note whether confirmed data has an operation/baseline from the current\n\t\t// schema or not.\n\t\tconst fromOlderVersion =\n\t\t\t!!confirmedResult.latestTimestamp &&\n\t\t\tcompareTimestampSchemaVersions(\n\t\t\t\tconfirmedResult.latestTimestamp,\n\t\t\t\tthis.ctx.time.now,\n\t\t\t) < 0;\n\n\t\tconst empty =\n\t\t\t!this.baseline &&\n\t\t\t!this.pendingOperations.length &&\n\t\t\t!this.confirmedOperations.length;\n\t\tif (empty) {\n\t\t\tthis.ctx.log('warn', `Tried to load Entity ${this.oid} with no data`);\n\t\t}\n\n\t\tconst updatedAtTimestamp =\n\t\t\tpendingResult.latestTimestamp ??\n\t\t\tconfirmedResult.latestTimestamp ??\n\t\t\tbaselineTimestamp;\n\t\tconst updatedAt = updatedAtTimestamp\n\t\t\t? getWallClockTime(updatedAtTimestamp)\n\t\t\t: 0;\n\n\t\tif (!pendingResult.view && !pendingResult.deleted && !empty) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'warn',\n\t\t\t\t`Entity ${this.oid} has no view, no deleted flag, and not empty`,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tview: pendingResult.view ?? undefined,\n\t\t\tdeleted: pendingResult.deleted,\n\t\t\tempty,\n\t\t\tfromOlderVersion,\n\t\t\tupdatedAt,\n\t\t\tlatestTimestamp: updatedAtTimestamp,\n\t\t\tauthz,\n\t\t};\n\t};\n\n\taddBaseline = (baseline: DocumentBaseline): void => {\n\t\t// opt out if our baseline is newer\n\t\tif (this.baseline && this.baseline.timestamp >= baseline.timestamp) {\n\t\t\treturn;\n\t\t}\n\t\tthis.baseline = baseline;\n\t\t// we can now drop any confirmed ops older than the baseline\n\t\twhile (this.confirmedOperations[0]?.timestamp < baseline.timestamp) {\n\t\t\tthis.confirmedOperations.shift();\n\t\t}\n\t};\n\n\t/**\n\t * @returns total number of new operations added\n\t */\n\taddConfirmedOperations = (operations: Operation[]): number => {\n\t\tlet totalAdded = 0;\n\t\t// the operations must be inserted in timestamp order\n\t\tfor (const op of operations) {\n\t\t\tconst index = this.confirmedOperations.findIndex(\n\t\t\t\t(o) => o.timestamp >= op.timestamp,\n\t\t\t);\n\t\t\tif (index !== -1) {\n\t\t\t\t// ensure we don't have a duplicate\n\t\t\t\tif (this.confirmedOperations[index].timestamp !== op.timestamp) {\n\t\t\t\t\t// otherwise, insert at the right place\n\t\t\t\t\tthis.confirmedOperations.splice(index, 0, op);\n\t\t\t\t\ttotalAdded++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// otherwise, append\n\t\t\t\tthis.confirmedOperations.push(op);\n\t\t\t\ttotalAdded++;\n\t\t\t}\n\t\t\t// FIXME: seems inefficient\n\t\t\t// remove this incoming op from pending if it's in there\n\t\t\tconst pendingPrior = this.pendingOperations.length;\n\t\t\tthis.discardPendingOperation(op);\n\t\t\ttotalAdded -= pendingPrior - this.pendingOperations.length;\n\t\t}\n\t\treturn totalAdded;\n\t};\n\n\taddPendingOperation = (operation: Operation) => {\n\t\tthis.pendingOperations.push(operation);\n\t};\n\n\taddEphemeralOperation = (operation: Operation) => {\n\t\tif (!this.ephemeralOperations) {\n\t\t\tthis.ephemeralOperations = [];\n\t\t}\n\t\tthis.ephemeralOperations.push(operation);\n\t};\n\n\tclearEphemeralOperations = () => {\n\t\tconst old = this.ephemeralOperations;\n\t\tthis.ephemeralOperations = [];\n\t\treturn old;\n\t};\n\n\tdiscardPendingOperation = (operation: Operation) => {\n\t\tthis.pendingOperations = this.pendingOperations.filter(\n\t\t\t(op) => op.timestamp !== operation.timestamp,\n\t\t);\n\t};\n\n\tprivate applyOperations = (\n\t\tbase: any,\n\t\tdeleted: boolean,\n\t\toperations: Operation[],\n\t\tlatestTimestamp: string | null,\n\t\tafter: string | null,\n\t): {\n\t\tview: any;\n\t\tlatestTimestamp: string | null;\n\t\tdeleted: boolean;\n\t\tfutureSeen: string | undefined;\n\t\tauthz?: AuthorizationKey;\n\t} => {\n\t\tlet futureSeen: string | undefined = undefined;\n\t\tlet authz: AuthorizationKey | undefined = undefined;\n\n\t\tconst now = this.ctx.time.now;\n\t\tfor (const op of operations) {\n\t\t\t// ignore ops before our after cutoff\n\t\t\tif (after && op.timestamp <= after) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// don't apply future ops\n\t\t\tif (compareTimestampSchemaVersions(op.timestamp, now) > 0) {\n\t\t\t\tfutureSeen = op.timestamp;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// we don't actually delete the view when a delete op\n\t\t\t// comes in. the view remains useful for calculating\n\t\t\t// undo operations.\n\t\t\tif (op.data.op === 'delete') {\n\t\t\t\tdeleted = true;\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tbase = applyPatch(base, op.data);\n\t\t\t\t\tif (op.data.op === 'initialize') {\n\t\t\t\t\t\tdeleted = false;\n\t\t\t\t\t\tif (op.authz) {\n\t\t\t\t\t\t\tauthz = op.authz;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t'critical',\n\t\t\t\t\t\t`Failed to apply operation to entity ${this.oid}: ${JSON.stringify(\n\t\t\t\t\t\t\top,\n\t\t\t\t\t\t)}`,\n\t\t\t\t\t\terr,\n\t\t\t\t\t);\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// track the latest timestamp\n\t\t\tif (!latestTimestamp || op.timestamp > latestTimestamp) {\n\t\t\t\tlatestTimestamp = op.timestamp;\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tview: base,\n\t\t\tlatestTimestamp: latestTimestamp ?? null,\n\t\t\tdeleted,\n\t\t\tfutureSeen,\n\t\t\tauthz,\n\t\t};\n\t};\n}\n\n/**\n * Represents the metadata for a group of entities underneath a Document.\n * Metadata is separated out this way so that these classes can be\n * garbage collected when the root Document goes out of scope.\n */\nexport class EntityFamilyMetadata {\n\tprivate ctx;\n\tprivate entities: Map<ObjectIdentifier, EntityMetadata> = new Map();\n\tprivate onPendingOperations;\n\tprivate rootOid: ObjectIdentifier;\n\n\tconstructor({\n\t\tctx,\n\t\tonPendingOperations,\n\t\trootOid,\n\t}: {\n\t\tctx: Context;\n\t\tonPendingOperations: (ops: Operation[]) => void;\n\t\trootOid: ObjectIdentifier;\n\t}) {\n\t\tthis.ctx = ctx;\n\t\tthis.rootOid = rootOid;\n\t\tthis.onPendingOperations = onPendingOperations;\n\t}\n\n\tget = (oid: ObjectIdentifier) => {\n\t\tassert(oid, 'oid is required');\n\t\tif (!this.entities.has(oid)) {\n\t\t\tthis.entities.set(oid, new EntityMetadata({ oid, ctx: this.ctx }));\n\t\t}\n\t\treturn this.entities.get(oid)!;\n\t};\n\n\tgetAllOids = () => {\n\t\treturn Array.from(this.entities.keys());\n\t};\n\n\taddConfirmedData = ({\n\t\tbaselines = [],\n\t\toperations = {},\n\t\tisLocal = false,\n\t}: {\n\t\tbaselines?: DocumentBaseline[];\n\t\toperations?: Record<ObjectIdentifier, Operation[]>;\n\t\tisLocal?: boolean;\n\t}) => {\n\t\tconst changes: Record<ObjectIdentifier, EntityChange> = {};\n\t\tfor (const baseline of baselines) {\n\t\t\tif (!areOidsRelated(this.rootOid, baseline.oid)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid baseline for entity ${this.rootOid}: ` +\n\t\t\t\t\t\tJSON.stringify(baseline),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.get(baseline.oid).addBaseline(baseline);\n\t\t\tchanges[baseline.oid] ??= { oid: baseline.oid, isLocal };\n\t\t}\n\t\tfor (const [oid, ops] of Object.entries(operations)) {\n\t\t\tif (!areOidsRelated(this.rootOid, oid)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid operations for entity ${this.rootOid}: ` +\n\t\t\t\t\t\tJSON.stringify(ops),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst added = this.get(oid).addConfirmedOperations(ops);\n\t\t\tif (added !== 0) {\n\t\t\t\tchanges[oid] ??= { oid, isLocal };\n\t\t\t}\n\t\t}\n\t\treturn Object.values(changes);\n\t};\n\n\t/**\n\t * Adds local, unconfirmed operations to the system.\n\t * The API is different here to streamline for the way\n\t * local changes are usually handled, as a list.\n\t */\n\taddPendingData = (operations: Operation[]) => {\n\t\t// when pending data is applied, we go ahead and\n\t\t// write all ephemeral changes first.\n\t\tthis.flushAllEphemeral();\n\n\t\tconst changes: Record<ObjectIdentifier, EntityChange> = {};\n\t\tfor (const op of operations) {\n\t\t\tthis.get(op.oid).addPendingOperation(op);\n\t\t\tchanges[op.oid] ??= { oid: op.oid, isLocal: true };\n\t\t}\n\t\tthis.onPendingOperations(operations);\n\t\treturn Object.values(changes);\n\t};\n\n\tprivate ephemeralMemo = new Array<Operation>();\n\tprivate flushAllEphemeral = () => {\n\t\tfor (const ent of this.entities.values()) {\n\t\t\tconst ops = ent.clearEphemeralOperations();\n\t\t\tif (ops) {\n\t\t\t\tthis.ephemeralMemo.push(...ops);\n\t\t\t}\n\t\t}\n\t\tif (this.ephemeralMemo.length) {\n\t\t\tconst ephemeralCopy = this.ephemeralMemo.slice();\n\t\t\t// must clear this first to avoid infinite recursion\n\t\t\tthis.ephemeralMemo.length = 0;\n\t\t\tthis.addPendingData(ephemeralCopy);\n\t\t}\n\t};\n\n\taddEphemeralData = (operations: Operation[]) => {\n\t\tconst changes: Record<ObjectIdentifier, EntityChange> = {};\n\t\tfor (const op of operations) {\n\t\t\tthis.get(op.oid).addEphemeralOperation(op);\n\t\t\tchanges[op.oid] ??= { oid: op.oid, isLocal: true };\n\t\t}\n\t\treturn Object.values(changes);\n\t};\n\n\treplaceAllData = ({\n\t\toperations = {},\n\t\tbaselines = [],\n\t}: {\n\t\toperations?: Record<ObjectIdentifier, Operation[]>;\n\t\tbaselines?: DocumentBaseline[];\n\t}) => {\n\t\tconst oids = Array.from(this.entities.keys());\n\t\tthis.entities.clear();\n\t\tconst changes: Record<ObjectIdentifier, EntityChange> = {};\n\t\t// changes apply to all the entities we removed things from, too\n\t\tfor (const oid of oids) {\n\t\t\tchanges[oid] = { oid, isLocal: false };\n\t\t}\n\t\tfor (const baseline of baselines) {\n\t\t\tif (!areOidsRelated(this.rootOid, baseline.oid)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid baseline for entity ${this.rootOid}: ` +\n\t\t\t\t\t\tJSON.stringify(baseline),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.get(baseline.oid).addBaseline(baseline);\n\t\t\tchanges[baseline.oid] ??= { oid: baseline.oid, isLocal: false };\n\t\t}\n\t\tfor (const [oid, ops] of Object.entries(operations)) {\n\t\t\tif (!areOidsRelated(this.rootOid, oid)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid operations for entity ${this.rootOid}: ` +\n\t\t\t\t\t\tJSON.stringify(ops),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.get(oid).addConfirmedOperations(ops);\n\t\t\tchanges[oid] ??= { oid, isLocal: false };\n\t\t}\n\t\treturn Object.values(changes);\n\t};\n\n\tdiscardPendingOperation = (operation: Operation) => {\n\t\tconst ent = this.entities.get(operation.oid);\n\t\tent?.discardPendingOperation(operation);\n\t};\n}\n", "import {\n\tBatcher,\n\tObjectIdentifier,\n\tOperation,\n\tPropertyName,\n\tgenerateId,\n\tgetOidRoot,\n\tgetUndoOperations,\n\tgroupPatchesByOid,\n\tisSuperseded,\n\toperationSupersedes,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { Entity } from './Entity.js';\nimport type { EntityStore } from './EntityStore.js';\n\nconst DEFAULT_BATCH_KEY = '@@default';\n\nexport interface OperationBatch {\n\trun: (fn: () => void) => this;\n\t/** @deprecated - use commit() */\n\tflush: () => Promise<void>;\n\tcommit: () => Promise<void>;\n\tdiscard: () => void;\n}\n\nexport class OperationBatcher {\n\tprivate batcher;\n\tprivate currentBatchKey = DEFAULT_BATCH_KEY;\n\tprivate defaultBatchTimeout: number;\n\tprivate ctx;\n\tprivate entities;\n\n\tconstructor({\n\t\tbatchTimeout = 200,\n\t\tctx,\n\t\tentities,\n\t}: {\n\t\tbatchTimeout?: number;\n\t\tctx: Context;\n\t\tentities: EntityStore;\n\t}) {\n\t\tthis.ctx = ctx;\n\t\tthis.entities = entities;\n\t\tthis.defaultBatchTimeout = batchTimeout;\n\t\tthis.batcher = new Batcher<Operation, { undoable?: boolean }>(\n\t\t\tthis.flushOperations,\n\t\t);\n\t\tthis.batcher.add({\n\t\t\tkey: DEFAULT_BATCH_KEY,\n\t\t\titems: [],\n\t\t\tmax: 100,\n\t\t\ttimeout: batchTimeout,\n\t\t\tuserData: { undoable: true },\n\t\t});\n\t}\n\n\tget isDefaultBatch() {\n\t\treturn this.currentBatchKey === DEFAULT_BATCH_KEY;\n\t}\n\n\tprivate flushOperations = async (\n\t\toperations: Operation[],\n\t\tbatchKey: string,\n\t\tmeta: { undoable?: boolean },\n\t) => {\n\t\tif (!operations.length) return;\n\t\tthis.ctx.log(\n\t\t\t'debug',\n\t\t\t'Flushing',\n\t\t\toperations.length,\n\t\t\t'operations from batch',\n\t\t\tbatchKey,\n\t\t\t'to storage / sync',\n\t\t);\n\n\t\t// next block of logic computes superseding rules to eliminate\n\t\t// operations which are 'overshadowed' by later ones on the same\n\t\t// key.\n\n\t\tconst committed: Operation[] = [];\n\t\tconst supersessions: Record<\n\t\t\tObjectIdentifier,\n\t\t\tSet<boolean | PropertyName>\n\t\t> = {};\n\t\tfor (let i = operations.length - 1; i >= 0; i--) {\n\t\t\tconst op = operations[i];\n\n\t\t\t// check for supersession from later operation which either\n\t\t\t// covers the whole id (true) or this key\n\t\t\tconst existingSupersession = supersessions[op.oid];\n\t\t\tif (existingSupersession && isSuperseded(op, existingSupersession)) {\n\t\t\t\tthis.entities.discardPendingOperation(op);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// determine if this operation supersedes others\n\t\t\tconst supersession = operationSupersedes(op);\n\t\t\tif (supersession !== false) {\n\t\t\t\tif (!supersessions[op.oid]) {\n\t\t\t\t\tsupersessions[op.oid] = new Set<boolean | PropertyName>();\n\t\t\t\t}\n\t\t\t\tsupersessions[op.oid]!.add(supersession);\n\t\t\t}\n\n\t\t\t// add this operation to final list\n\t\t\tcommitted.unshift(op);\n\t\t}\n\n\t\t// rewrite timestamps of all operations to now - this preserves\n\t\t// the linear history of operations which are sent to the server.\n\t\t// even if multiple batches are spun up in parallel and flushed\n\t\t// after delay, the final operations in each one should reflect\n\t\t// when the batch flushed, not when the changes were made.\n\t\t// This also corresponds to user-observed behavior, since unconfirmed\n\t\t// operations are applied universally after confirmed operations locally,\n\t\t// so even operations which were made before a remote operation but\n\t\t// have not been confirmed yet will appear to come after the remote one\n\t\t// despite the provisional timestamp being earlier\n\t\t// NOTE: this MUST be mutating the original operation object! this timestamp\n\t\t// also serves as a unique ID for deduplication later.\n\n\t\t// NOTE: need to rewind back in order to set timestamps correctly.\n\t\t// cannot be done in reversed loop above or timestamps would be\n\t\t// in reverse order.\n\t\tfor (const op of committed) {\n\t\t\top.timestamp = this.ctx.time.now;\n\t\t}\n\t\tawait this.commitOperations(committed, meta);\n\t};\n\n\t/**\n\t * Immediately flushes operations to storage / sync.\n\t * Providing source to second arg skips hydrating related\n\t * Entity from storage, which is useful when that Entity\n\t * isn't in storage (i.e. still creating) or just to speed\n\t * up the commit.\n\t */\n\tcommitOperations = async (\n\t\toperations: Operation[],\n\t\tmeta: { undoable?: boolean; source?: Entity },\n\t) => {\n\t\tif (!operations.length) return;\n\t\t// now is the time to decide on what the undo operations will\n\t\t// look like, based on the confirmed view of the related entities.\n\t\tif (meta.undoable) {\n\t\t\tconst undo = await this.createUndo({\n\t\t\t\tops: operations,\n\t\t\t\tsource: meta.source,\n\t\t\t});\n\t\t\tif (undo) this.ctx.undoHistory.addUndo(undo);\n\t\t}\n\t\t// ship it out to EntityStore to compute final snapshots\n\t\t// write to storage and refresh entities and queries\n\t\tawait this.entities.addData({\n\t\t\toperations,\n\t\t\tbaselines: [],\n\t\t\tisLocal: true,\n\t\t});\n\t};\n\n\t/**\n\t * Adds operations to the active batch.\n\t */\n\taddOperations = (operations: Operation[]) => {\n\t\tif (!operations.length) return;\n\t\tthis.batcher.add({\n\t\t\tkey: this.currentBatchKey,\n\t\t\titems: operations,\n\t\t});\n\t\tthis.ctx.log(\n\t\t\t`debug`,\n\t\t\t'added',\n\t\t\toperations.length,\n\t\t\t'ops to batch',\n\t\t\tthis.currentBatchKey,\n\t\t\t', size = ',\n\t\t\tthis.batcher.getSize(this.currentBatchKey),\n\t\t);\n\t};\n\n\tbatch = ({\n\t\tundoable = true,\n\t\tbatchName = generateId(),\n\t\tmax = null,\n\t\ttimeout = this.defaultBatchTimeout,\n\t}: {\n\t\t/** Allows turning off undo for this batch, making it 'permanent' */\n\t\tundoable?: boolean;\n\t\t/**\n\t\t * Provide a stable name to any invocation of .batch() and the changes made\n\t\t * within run() will all be added to the same batch. If a batch hits the max\n\t\t * limit or timeout and is flushed, the name will be reused for a new batch\n\t\t * automatically. Provide a stable name to make changes from anywhere in your\n\t\t * app to be grouped together in the same batch with the same limit behavior.\n\t\t *\n\t\t * Limit configuration provided to each invocation of .batch() with the same\n\t\t * name will overwrite any other invocation's limit configuration. It's\n\t\t * recommended to provide limits in one place and only provide a name\n\t\t * in others.\n\t\t */\n\t\tbatchName?: string;\n\t\t/**\n\t\t * The maximum number of operations the batch will hold before flushing\n\t\t * automatically. If null, the batch will not flush automatically based\n\t\t * on operation count.\n\t\t */\n\t\tmax?: number | null;\n\t\t/**\n\t\t * The number of milliseconds to wait before flushing the batch automatically.\n\t\t * If null, the batch will not flush automatically based on time. It is not\n\t\t * recommended to set this to null, as an unflushed batch will never be written\n\t\t * to storage or sync. If you do require undefined timing in a batch, make sure\n\t\t * to always call .commit() on the batch yourself.\n\t\t */\n\t\ttimeout?: number | null;\n\t} = {}): OperationBatch => {\n\t\tconst internalBatch = this.batcher.add({\n\t\t\tkey: batchName,\n\t\t\tmax,\n\t\t\ttimeout,\n\t\t\titems: [],\n\t\t\tuserData: { undoable },\n\t\t});\n\t\tconst externalApi = {\n\t\t\trun: (fn: () => void) => {\n\t\t\t\t// while the provided function runs, operations are forwarded\n\t\t\t\t// to the new batch instead of default. this relies on the function\n\t\t\t\t// being synchronous.\n\t\t\t\tthis.currentBatchKey = batchName;\n\t\t\t\tfn();\n\t\t\t\tthis.currentBatchKey = DEFAULT_BATCH_KEY;\n\t\t\t\treturn externalApi;\n\t\t\t},\n\t\t\tcommit: async () => {\n\t\t\t\t// before running a batch, the default operations must be flushed\n\t\t\t\t// this better preserves undo history behavior...\n\t\t\t\t// if we left the default batch open while flushing a named batch,\n\t\t\t\t// then the default batch would be flushed after the named batch,\n\t\t\t\t// and the default batch could contain operations both prior and\n\t\t\t\t// after the named batch. this would result in a confusing undo\n\t\t\t\t// history where the first undo might reverse changes before and\n\t\t\t\t// after a set of other changes.\n\t\t\t\tawait this.batcher.flush(DEFAULT_BATCH_KEY);\n\t\t\t\treturn internalBatch.flush();\n\t\t\t},\n\t\t\tflush: () => externalApi.commit(),\n\t\t\tdiscard: () => {\n\t\t\t\tthis.batcher.discard(batchName);\n\t\t\t},\n\t\t};\n\t\treturn externalApi;\n\t};\n\n\tflushAll = () => {\n\t\tthis.ctx.log('debug', 'Flushing all operations');\n\t\treturn Promise.all(this.batcher.flushAll());\n\t};\n\n\tprivate createUndo = async (data: {\n\t\tops: Operation[];\n\t\tsource?: Entity;\n\t\tisRedo?: boolean;\n\t}) => {\n\t\t// this can't be done on-demand because we rely on the current\n\t\t// state of the entities to calculate the inverse operations.\n\t\tconst inverseOps = await this.getInverseOperations(data);\n\n\t\tif (!inverseOps.length) return null;\n\n\t\treturn async () => {\n\t\t\tconst redo = await this.createUndo({\n\t\t\t\tops: inverseOps,\n\t\t\t\tsource: data.source,\n\t\t\t\tisRedo: true,\n\t\t\t});\n\t\t\t// set time to now for all undo operations, they're happening now.\n\t\t\tfor (const op of inverseOps) {\n\t\t\t\top.timestamp = this.ctx.time.now;\n\t\t\t}\n\n\t\t\tthis.ctx.log(\n\t\t\t\t'debug',\n\t\t\t\tdata.isRedo ? 'Redo' : 'Undo',\n\t\t\t\tinverseOps,\n\t\t\t\t'\\n was \\n',\n\t\t\t\tdata.ops,\n\t\t\t);\n\n\t\t\tawait this.commitOperations(\n\t\t\t\tinverseOps,\n\t\t\t\t// undos should not generate their own undo operations\n\t\t\t\t// since they already calculate redo as the inverse.\n\t\t\t\t{ undoable: false },\n\t\t\t);\n\t\t\treturn redo;\n\t\t};\n\t};\n\tprivate getInverseOperations = async ({\n\t\tops,\n\t\tsource,\n\t}: {\n\t\tops: Operation[];\n\t\tsource?: Entity;\n\t}) => {\n\t\tconst grouped = groupPatchesByOid(ops);\n\t\tconst inverseOps: Operation[] = [];\n\t\tconst getNow = () => this.ctx.time.now;\n\t\tawait Promise.all(\n\t\t\tObject.entries(grouped).map(async ([oid, patches]): Promise<void> => {\n\t\t\t\tconst entity = source ?? (await this.entities.hydrate(getOidRoot(oid)));\n\t\t\t\t// TODO: this is getting the rebased baseline? how? are ops being submitted early?\n\t\t\t\tconst viewData = entity?.__getViewData__(oid, 'confirmed');\n\t\t\t\tif (!viewData) {\n\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t'warn',\n\t\t\t\t\t\t'could not find entity',\n\t\t\t\t\t\toid,\n\t\t\t\t\t\t'for undo operation',\n\t\t\t\t\t\tops,\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst inverse = getUndoOperations(oid, viewData.view, patches, getNow);\n\t\t\t\tinverseOps.unshift(...inverse);\n\t\t\t}),\n\t\t);\n\t\treturn inverseOps;\n\t};\n}\n", "import { FileData } from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { Entity } from '../entities/Entity.js';\nimport { Disposable } from '../internal.js';\nimport { Sync } from '../sync/Sync.js';\nimport { EntityFile, MARK_FAILED, UPDATE } from './EntityFile.js';\n\nexport class FileManager extends Disposable {\n\tprivate sync;\n\tprivate context;\n\n\tprivate cache = new Map<string, EntityFile>();\n\n\tconstructor({ sync, context }: { sync: Sync; context: Context }) {\n\t\tsuper();\n\t\tthis.sync = sync;\n\t\tthis.context = context;\n\t\tthis.addDispose(\n\t\t\tthis.context.internalEvents.subscribe(\n\t\t\t\t'fileUploaded',\n\t\t\t\tthis.onFileUploaded,\n\t\t\t),\n\t\t);\n\t}\n\n\tadd = async (file: FileData, parent: Entity) => {\n\t\t// immediately cache the file\n\t\tlet entityFile = this.cache.get(file.id);\n\t\tif (!entityFile) {\n\t\t\tentityFile = new EntityFile(file.id, { ctx: this.context, parent });\n\t\t\tthis.cache.set(file.id, entityFile);\n\t\t}\n\n\t\tif (!file.remote) {\n\t\t\t// immediately update local files.\n\t\t\tentityFile[UPDATE](file);\n\t\t}\n\t\t// this will download any original remote file and trigger a re-upload to the\n\t\t// new file's identity, in addition to storing it on disk\n\t\tconst processedFile = await (\n\t\t\tawait this.context.files\n\t\t).add(file, { cloneRemote: true });\n\t\tentityFile[UPDATE](processedFile);\n\t};\n\n\t/**\n\t * Immediately returns an EntityFile to use, then either loads\n\t * the file from cache, local database, or the server.\n\t */\n\tget = (\n\t\tid: string,\n\t\toptions: { downloadRemote?: boolean; ctx: Context; parent: Entity },\n\t) => {\n\t\tif (this.cache.has(id)) {\n\t\t\treturn this.cache.get(id)!;\n\t\t}\n\t\tconst file = new EntityFile(id, options);\n\t\tthis.cache.set(id, file);\n\t\tthis.load(file);\n\t\treturn file;\n\t};\n\n\tprivate load = async (file: EntityFile) => {\n\t\tconst fileData = await (await this.context.files).get(file.id);\n\t\t// immediately apply any file data we have\n\t\tif (fileData) {\n\t\t\tfile[UPDATE](fileData);\n\t\t}\n\n\t\tif (!fileData?.url && (!fileData || fileData.remote)) {\n\t\t\t// maybe we don't have it yet, it might be on the server still.\n\t\t\ttry {\n\t\t\t\t// if not online, enqueue this for whenever we go online.\n\t\t\t\tif (this.sync.status !== 'active') {\n\t\t\t\t\tthis.context.log(\n\t\t\t\t\t\t'info',\n\t\t\t\t\t\t'Sync is not active, waiting for online to load file',\n\t\t\t\t\t\tfile.id,\n\t\t\t\t\t\tfile.name,\n\t\t\t\t\t);\n\t\t\t\t\tconst unsub = this.sync.subscribe('onlineChange', (online) => {\n\t\t\t\t\t\tif (online) {\n\t\t\t\t\t\t\tunsub();\n\t\t\t\t\t\t\tthis.load(file);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst result = await this.sync.getFile(file.id);\n\t\t\t\tif (result.success) {\n\t\t\t\t\t// avoid overwriting local values except for url\n\t\t\t\t\tconst copyWithUrl: FileData = {\n\t\t\t\t\t\t...result.data,\n\t\t\t\t\t\t...fileData,\n\t\t\t\t\t\turl: result.data.url,\n\t\t\t\t\t};\n\t\t\t\t\tawait (await this.context.files).update(copyWithUrl);\n\t\t\t\t\tfile[UPDATE](result.data);\n\t\t\t\t} else {\n\t\t\t\t\tthis.context.log('error', 'Failed to load file', result);\n\t\t\t\t\tif (!fileData) {\n\t\t\t\t\t\t// only mark failed if we have no local data to fall back to\n\t\t\t\t\t\tfile[MARK_FAILED](result.error?.toString());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tthis.context.log('error', 'Failed to load file', err);\n\t\t\t\tif (!fileData) {\n\t\t\t\t\t// only mark failed if we have no local data to fall back to\n\t\t\t\t\tfile[MARK_FAILED](err instanceof Error ? err.message : String(err));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate onFileUploaded = async (data: FileData) => {\n\t\tthis.context.log('debug', 'Marking file as uploaded', data.id);\n\t\t(await this.context.files).onUploaded(data.id);\n\t};\n}\n", "import { CollectionIndexFilter, hashObject } from '@verdant-web/common';\nimport { Entity } from '../entities/Entity.js';\n\nfunction existsFilter<T>(x: T | null): x is T {\n\treturn x !== null;\n}\n\nexport function filterResultSet(results: any): any {\n\tif (Array.isArray(results)) {\n\t\treturn results.map(filterResultSet).filter(existsFilter);\n\t} else if (results instanceof Entity) {\n\t\treturn results.deleted ? null : results;\n\t} else {\n\t\treturn results;\n\t}\n}\n\nexport function areIndexesEqual(\n\ta?: CollectionIndexFilter,\n\tb?: CollectionIndexFilter,\n) {\n\treturn (!a && !b) || (a && b && hashObject(a) === hashObject(b));\n}\n", "import { EventSubscriber } from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { Entity } from '../entities/Entity.js';\nimport { Disposable } from '../utils/Disposable.js';\nimport { filterResultSet } from './utils.js';\n\nexport type BaseQueryEvents = {\n\tchange: (value: any) => void;\n\tstatusChange: (status: QueryStatus) => void;\n};\n\nexport type BaseQueryOptions<T> = {\n\tcontext: Context;\n\tinitial: T;\n\tcollection: string;\n\tkey: string;\n\tshouldUpdate?: (updatedCollections: string[]) => boolean;\n};\n\nexport type QueryStatus = 'initial' | 'initializing' | 'revalidating' | 'ready';\n\nexport const ON_ALL_UNSUBSCRIBED = Symbol('ON_ALL_UNSUBSCRIBED');\nexport const UPDATE = Symbol('UPDATE');\n\n// export interface BaseQuery<T> {\n// \tsubscribe(event: 'change', callback: (value: T) => void): () => void;\n// \tsubscribe(event: 'statusChange', callback: (status: QueryStatus) => void): () => void;\n// \tsubscribe(callback: (value: T) => void): () => void;\n// }\n\nexport abstract class BaseQuery<T> extends Disposable {\n\tprivate _rawValue;\n\tprivate _value;\n\n\tprivate _events;\n\tprivate _internalUnsubscribes: (() => void)[] = [];\n\tprivate _allUnsubscribedHandler?: (query: BaseQuery<T>) => void;\n\tprivate _status: QueryStatus = 'initial';\n\tprivate _executionPromise: Promise<T> | null = null;\n\n\tprotected context;\n\n\treadonly collection;\n\treadonly key;\n\treadonly isListQuery;\n\n\tconstructor({\n\t\tinitial,\n\t\tcontext,\n\t\tcollection,\n\t\tkey,\n\t\tshouldUpdate,\n\t}: BaseQueryOptions<T>) {\n\t\tsuper();\n\t\tthis._rawValue = initial;\n\t\tthis._value = initial;\n\t\tthis.isListQuery = Array.isArray(initial);\n\t\tthis._events = new EventSubscriber<BaseQueryEvents>(\n\t\t\t(event: keyof BaseQueryEvents) => {\n\t\t\t\tif (event === 'change') {\n\t\t\t\t\tthis._allUnsubscribedHandler?.(this);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t\tthis.context = context;\n\t\tthis.key = key;\n\t\tthis.collection = collection;\n\t\tconst shouldUpdateFn =\n\t\t\tshouldUpdate ||\n\t\t\t((collections: string[]) => collections.includes(collection));\n\t\tthis.addDispose(\n\t\t\tthis.context.entityEvents.subscribe(\n\t\t\t\t'collectionsChanged',\n\t\t\t\t(collections) => {\n\t\t\t\t\tif (shouldUpdateFn(collections)) {\n\t\t\t\t\t\tthis.context.log('info', 'Updating query', this.key);\n\t\t\t\t\t\t// immediately refilter the result set - deleted\n\t\t\t\t\t\t// entities will already be nulled out\n\t\t\t\t\t\t// this.refreshValue();\n\t\t\t\t\t\tthis.execute();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t);\n\t\t// TODO: subscribe to document changes and update if necessary.\n\t}\n\n\tget current() {\n\t\treturn this._value;\n\t}\n\n\tget resolved() {\n\t\tif (this.status === 'ready') return Promise.resolve(this._value);\n\t\treturn this._executionPromise ?? this.execute();\n\t}\n\n\tget subscribed() {\n\t\treturn this._events.totalSubscriberCount() > 0;\n\t}\n\n\tget status() {\n\t\treturn this._status;\n\t}\n\n\tprivate set status(v: QueryStatus) {\n\t\tif (this._status === v) return;\n\t\tthis._status = v;\n\t\tthis._events.emit('statusChange', this._status);\n\t}\n\n\tget hasDeleted() {\n\t\tif (this.isListQuery) {\n\t\t\treturn (this._rawValue as any[]).length !== (this._value as any[]).length;\n\t\t}\n\t\treturn !!this._rawValue && !this._value;\n\t}\n\n\t/**\n\t * Subscribe to changes in the query value.\n\t *\n\t * @deprecated use the two parameter form instead\n\t */\n\tsubscribe(callback: (value: T) => void): () => void;\n\t/**\n\t * Subscribe to changes in the query value.\n\t */\n\tsubscribe(event: 'change', callback: (value: T) => void): () => void;\n\t/**\n\t * Subscribe to changes in the query state.\n\t */\n\tsubscribe(\n\t\tevent: 'statusChange',\n\t\tcallback: (status: QueryStatus) => void,\n\t): () => void;\n\tsubscribe(eventOrCallback: any, callback?: any) {\n\t\t// change subscription has special behavior...\n\t\tif (callback === undefined && typeof eventOrCallback === 'function') {\n\t\t\t// accessing for side effects... eh\n\t\t\tthis.resolved;\n\t\t\treturn this._events.subscribe('change', eventOrCallback);\n\t\t} else if (eventOrCallback === 'change' && callback !== undefined) {\n\t\t\t// accessing for side effects... eh\n\t\t\tthis.resolved;\n\t\t\treturn this._events.subscribe('change', callback);\n\t\t} else if (\n\t\t\teventOrCallback === 'statusChange' &&\n\t\t\ttypeof callback === 'function'\n\t\t) {\n\t\t\treturn this._events.subscribe(eventOrCallback, callback);\n\t\t} else {\n\t\t\tthrow new Error('Invalid invocation of Query.subscribe');\n\t\t}\n\t}\n\n\tprotected setValue = (value: T) => {\n\t\tthis._rawValue = value;\n\t\tthis.subscribeToDeleteAndRestore(this._rawValue);\n\t\tconst filtered = filterResultSet(value);\n\n\t\t// prevent excess change notifications by diffing\n\t\t// value by identity for single-value queries,\n\t\t// and by item identity for multi-value\n\t\tlet changed = true;\n\t\t// always fire change when going from initial to ready\n\t\tif (this.status === 'initializing' || this.status === 'initial') {\n\t\t\tchanged = true;\n\t\t} else {\n\t\t\t// compare values by identity, after filtering.\n\t\t\tif (this.isListQuery) {\n\t\t\t\tif (\n\t\t\t\t\t(this._value as any[]).length === (filtered as any[]).length &&\n\t\t\t\t\t(this._value as any[]).every((v, i) => v === (filtered as any[])[i])\n\t\t\t\t) {\n\t\t\t\t\tchanged = false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (this._value === filtered) {\n\t\t\t\t\tchanged = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis._value = filtered;\n\n\t\tif (changed) {\n\t\t\tthis.context.log('debug', 'Query value changed', this.key);\n\t\t\tthis._events.emit('change', this._value);\n\t\t}\n\t\tthis.status = 'ready';\n\t};\n\n\t// re-applies filtering if results have changed\n\tprotected refreshValue = () => {\n\t\tthis.setValue(this._rawValue);\n\t};\n\n\tprivate subscribeToDeleteAndRestore = (value: T) => {\n\t\twhile (this._internalUnsubscribes.length) {\n\t\t\tthis._internalUnsubscribes.pop()?.();\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tvalue.forEach((entity: any) => {\n\t\t\t\tif (entity instanceof Entity) {\n\t\t\t\t\tthis._internalUnsubscribes.push(\n\t\t\t\t\t\tentity.subscribe('delete', this.refreshValue),\n\t\t\t\t\t);\n\t\t\t\t\tthis._internalUnsubscribes.push(\n\t\t\t\t\t\tentity.subscribe('restore', this.refreshValue),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t} else if (value instanceof Entity) {\n\t\t\tthis._internalUnsubscribes.push(\n\t\t\t\tvalue.subscribe('delete', this.refreshValue),\n\t\t\t);\n\t\t\tthis._internalUnsubscribes.push(\n\t\t\t\tvalue.subscribe('restore', () => {\n\t\t\t\t\tthis.refreshValue();\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t};\n\n\texecute = () => {\n\t\tconst startTime = new Date();\n\t\tthis.context.log(\n\t\t\t'debug',\n\t\t\t`[${startTime.toLocaleTimeString()}]`,\n\t\t\t'Executing query',\n\t\t\tthis.key,\n\t\t);\n\n\t\tif (this.status === 'initial') {\n\t\t\tthis.status = 'initializing';\n\t\t} else if (this.status === 'ready') {\n\t\t\tthis.status = 'revalidating';\n\t\t}\n\t\t// no status change needed if already in a 'running' status.\n\n\t\tthis._executionPromise = this.run()\n\t\t\t.then(() => this._value)\n\t\t\t.catch((err) => {\n\t\t\t\tif (err instanceof Error) {\n\t\t\t\t\tif (\n\t\t\t\t\t\terr.name === 'InvalidStateError' ||\n\t\t\t\t\t\terr.name === 'InvalidAccessError'\n\t\t\t\t\t) {\n\t\t\t\t\t\t// possibly accessing db while it's closed. not much we can do.\n\t\t\t\t\t\treturn this._value;\n\t\t\t\t\t}\n\t\t\t\t\tthrow err;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error('Unknown error executing query');\n\t\t\t\t}\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tconst endTime = new Date();\n\t\t\t\tconst duration = endTime.getTime() - startTime.getTime();\n\t\t\t\tthis.context.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t`[${endTime.toLocaleTimeString()}]`,\n\t\t\t\t\t'Query executed',\n\t\t\t\t\tthis.key,\n\t\t\t\t\t`Duration: ${duration}ms`,\n\t\t\t\t);\n\t\t\t});\n\t\treturn this._executionPromise;\n\t};\n\tprotected abstract run(): Promise<void>;\n\n\t[ON_ALL_UNSUBSCRIBED] = (handler: (query: BaseQuery<T>) => void) => {\n\t\tthis._allUnsubscribedHandler = handler;\n\t};\n\n\tget __rawValue() {\n\t\treturn this._rawValue;\n\t}\n}\n", "import { createOid } from '@verdant-web/common';\nimport { BaseQuery, BaseQueryOptions } from './BaseQuery.js';\n\nexport class GetQuery<T> extends BaseQuery<T | null> {\n\tprivate hydrate;\n\tprivate oid;\n\n\tconstructor({\n\t\tid,\n\t\thydrate,\n\t\t...rest\n\t}: {\n\t\tid: string;\n\t\thydrate: (oid: string) => Promise<T>;\n\t} & Omit<BaseQueryOptions<T | null>, 'initial'>) {\n\t\tsuper({\n\t\t\tinitial: null,\n\t\t\t...rest,\n\t\t});\n\t\tthis.oid = createOid(rest.collection, id);\n\t\tthis.hydrate = hydrate;\n\t}\n\n\tprotected run = async () => {\n\t\tconst value = await this.hydrate(this.oid);\n\t\tthis.setValue(value);\n\t};\n}\n", "import { CollectionFilter } from '@verdant-web/common';\nimport { BaseQuery, BaseQueryOptions, UPDATE } from './BaseQuery.js';\nimport { areIndexesEqual } from './utils.js';\n\nexport class FindOneQuery<T> extends BaseQuery<T | null> {\n\tprivate index;\n\tprivate hydrate;\n\n\tconstructor({\n\t\tindex,\n\t\thydrate,\n\t\t...rest\n\t}: {\n\t\tindex?: CollectionFilter;\n\t\thydrate: (oid: string) => Promise<T>;\n\t} & Omit<BaseQueryOptions<T | null>, 'initial'>) {\n\t\tsuper({\n\t\t\tinitial: null,\n\t\t\t...rest,\n\t\t});\n\t\tthis.index = index;\n\t\tthis.hydrate = hydrate;\n\t}\n\n\tprotected run = async () => {\n\t\tconst oid = await (\n\t\t\tawait this.context.documents\n\t\t).findOneOid({\n\t\t\tcollection: this.collection,\n\t\t\tindex: this.index,\n\t\t});\n\t\tthis.setValue(oid ? await this.hydrate(oid) : null);\n\t};\n\n\t[UPDATE] = (index: CollectionFilter | undefined) => {\n\t\tif (areIndexesEqual(this.index, index)) return;\n\t\tthis.index = index;\n\t\tthis.execute();\n\t};\n}\n", "import { CollectionFilter } from '@verdant-web/common';\nimport { BaseQuery, BaseQueryOptions, UPDATE } from './BaseQuery.js';\nimport { areIndexesEqual } from './utils.js';\n\nexport class FindPageQuery<T> extends BaseQuery<T[]> {\n\tprivate index;\n\tprivate hydrate;\n\tprivate _pageSize: number;\n\tprivate _page: number;\n\tprivate _hasNextPage: boolean = false;\n\n\tget pageSize() {\n\t\treturn this._pageSize;\n\t}\n\n\tget page() {\n\t\treturn this._page;\n\t}\n\n\tget hasNextPage() {\n\t\treturn this._hasNextPage;\n\t}\n\n\tget hasPreviousPage() {\n\t\treturn this._page > 0;\n\t}\n\n\tconstructor({\n\t\tindex,\n\t\thydrate,\n\t\tpageSize,\n\t\tpage,\n\t\t...rest\n\t}: {\n\t\tindex?: CollectionFilter;\n\t\thydrate: (oid: string) => Promise<T>;\n\t\tpageSize: number;\n\t\tpage: number;\n\t} & Omit<BaseQueryOptions<T[]>, 'initial'>) {\n\t\tsuper({\n\t\t\tinitial: [],\n\t\t\t...rest,\n\t\t});\n\t\tthis.index = index;\n\t\tthis.hydrate = hydrate;\n\t\tthis._pageSize = pageSize;\n\t\tthis._page = page;\n\t}\n\n\tprotected run = async () => {\n\t\tconst { result, hasNextPage } = await (\n\t\t\tawait this.context.documents\n\t\t).findAllOids({\n\t\t\tcollection: this.collection,\n\t\t\tindex: this.index,\n\t\t\tlimit: this._pageSize,\n\t\t\toffset: this._page * this._pageSize,\n\t\t});\n\t\tthis._hasNextPage = hasNextPage;\n\t\tthis.setValue(await Promise.all(result.map(this.hydrate)));\n\t};\n\n\tnextPage = async () => {\n\t\tif (!this.hasNextPage) return;\n\n\t\tthis._page++;\n\t\tawait this.run();\n\t};\n\n\tpreviousPage = async () => {\n\t\tif (this._page === 0) return;\n\n\t\tthis._page--;\n\t\tawait this.run();\n\t};\n\n\tsetPage = async (page: number) => {\n\t\tthis._page = page;\n\t\tawait this.run();\n\t};\n\n\t[UPDATE] = (index: CollectionFilter | undefined) => {\n\t\tif (areIndexesEqual(this.index, index)) return;\n\t\tthis.index = index;\n\t\tthis.execute();\n\t};\n}\n", "import { CollectionFilter } from '@verdant-web/common';\nimport { BaseQuery, BaseQueryOptions, UPDATE } from './BaseQuery.js';\nimport { areIndexesEqual } from './utils.js';\n\nexport class FindInfiniteQuery<T> extends BaseQuery<T[]> {\n\tprivate index;\n\tprivate hydrate;\n\tprivate _upToPage = 1;\n\tprivate _pageSize: number;\n\tprivate _hasNextPage: boolean = false;\n\n\tget pageSize() {\n\t\treturn this._pageSize;\n\t}\n\n\tget hasMore() {\n\t\treturn this._hasNextPage;\n\t}\n\n\tconstructor({\n\t\thydrate,\n\t\tpageSize,\n\t\tindex,\n\t\t...rest\n\t}: {\n\t\thydrate: (oid: string) => Promise<T>;\n\t\tpageSize: number;\n\t\tindex?: CollectionFilter;\n\t} & Omit<BaseQueryOptions<T[]>, 'initial'>) {\n\t\tsuper({\n\t\t\tinitial: [],\n\t\t\t...rest,\n\t\t});\n\t\tthis.index = index;\n\t\tthis.hydrate = hydrate;\n\t\tthis._pageSize = pageSize;\n\t}\n\n\tprotected run = async () => {\n\t\tconst { result, hasNextPage } = await (\n\t\t\tawait this.context.documents\n\t\t).findAllOids({\n\t\t\tcollection: this.collection,\n\t\t\tlimit: this._pageSize * this._upToPage,\n\t\t\toffset: 0,\n\t\t\tindex: this.index,\n\t\t});\n\t\tthis._hasNextPage = hasNextPage;\n\t\tthis.setValue(await Promise.all(result.map(this.hydrate)));\n\t};\n\n\tpublic loadMore = async () => {\n\t\tconst { result, hasNextPage } = await (\n\t\t\tawait this.context.documents\n\t\t).findAllOids({\n\t\t\tcollection: this.collection,\n\t\t\tlimit: this._pageSize,\n\t\t\toffset: this._pageSize * this._upToPage,\n\t\t\tindex: this.index,\n\t\t});\n\t\tthis._hasNextPage = hasNextPage;\n\t\tthis._upToPage++;\n\t\tthis.setValue([\n\t\t\t...this.current,\n\t\t\t...(await Promise.all(result.map(this.hydrate))),\n\t\t]);\n\t};\n\n\t[UPDATE] = (index: CollectionFilter | undefined) => {\n\t\tif (areIndexesEqual(this.index, index)) return;\n\t\tthis.index = index;\n\t\tthis.execute();\n\t};\n}\n", "import { CollectionFilter } from '@verdant-web/common';\nimport { BaseQuery, BaseQueryOptions, UPDATE } from './BaseQuery.js';\nimport { areIndexesEqual } from './utils.js';\n\nexport class FindAllQuery<T> extends BaseQuery<T[]> {\n\tprivate index;\n\tprivate hydrate;\n\n\tconstructor({\n\t\tindex,\n\t\thydrate,\n\t\t...rest\n\t}: {\n\t\tindex?: CollectionFilter;\n\t\thydrate: (oid: string) => Promise<T>;\n\t} & Omit<BaseQueryOptions<T[]>, 'initial'>) {\n\t\tsuper({\n\t\t\tinitial: [],\n\t\t\t...rest,\n\t\t});\n\t\tthis.index = index;\n\t\tthis.hydrate = hydrate;\n\t}\n\n\tprotected run = async () => {\n\t\tconst { result: oids } = await (\n\t\t\tawait this.context.documents\n\t\t).findAllOids({\n\t\t\tcollection: this.collection,\n\t\t\tindex: this.index,\n\t\t});\n\t\tthis.context.log(\n\t\t\t'debug',\n\t\t\t`FindAllQuery: ${oids.length} oids found: ${oids}`,\n\t\t);\n\t\tthis.setValue(await Promise.all(oids.map(this.hydrate)));\n\t};\n\n\t[UPDATE] = (index: CollectionFilter | undefined) => {\n\t\tif (areIndexesEqual(this.index, index)) return;\n\t\tthis.index = index;\n\t\tthis.execute();\n\t};\n}\n", "import {\n\tAuthorizationKey,\n\tCollectionFilter,\n\thashObject,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { EntityStore } from '../entities/EntityStore.js';\nimport { GetQuery } from './GetQuery.js';\nimport { QueryCache } from './QueryCache.js';\nimport { FindOneQuery } from './FindOneQuery.js';\nimport { FindPageQuery } from './FindPageQuery.js';\nimport { FindInfiniteQuery } from './FindInfiniteQuery.js';\nimport { FindAllQuery } from './FindAllQuery.js';\nimport { DocumentManager } from '../entities/DocumentManager.js';\nimport { ObjectEntity } from '../index.js';\nimport { UPDATE } from './BaseQuery.js';\n\nexport class CollectionQueries<\n\tT extends ObjectEntity<any, any>,\n\tInit,\n\tFilter extends CollectionFilter,\n> {\n\tprivate cache;\n\tprivate collection;\n\tprivate hydrate: (oid: string) => Promise<T>;\n\tprivate context;\n\tprivate documentManager;\n\n\tput: (\n\t\tinit: Init,\n\t\toptions?: { undoable?: boolean; access?: AuthorizationKey },\n\t) => Promise<T>;\n\tdelete: (id: string, options?: { undoable?: boolean }) => Promise<void>;\n\tdeleteAll: (ids: string[], options?: { undoable?: boolean }) => Promise<void>;\n\tclone: (\n\t\tentity: ObjectEntity<any, any>,\n\t\toptions?: {\n\t\t\tundoable?: boolean;\n\t\t\taccess?: AuthorizationKey;\n\t\t\tprimaryKey?: string;\n\t\t},\n\t) => Promise<T>;\n\n\tconstructor({\n\t\tcollection,\n\t\tcache,\n\t\tentities,\n\t\tcontext,\n\t\tdocumentManager,\n\t}: {\n\t\tcollection: string;\n\t\tcache: QueryCache;\n\t\tentities: EntityStore;\n\t\tcontext: Context;\n\t\tdocumentManager: DocumentManager<any>;\n\t}) {\n\t\tthis.cache = cache;\n\t\tthis.collection = collection;\n\t\tthis.hydrate = entities.hydrate as any;\n\t\tthis.context = context;\n\t\tthis.documentManager = documentManager;\n\n\t\tthis.put = this.documentManager.create.bind(\n\t\t\tthis.documentManager,\n\t\t\tthis.collection,\n\t\t);\n\t\tthis.delete = this.documentManager.delete.bind(\n\t\t\tthis.documentManager,\n\t\t\tthis.collection,\n\t\t);\n\t\tthis.deleteAll = this.documentManager.deleteAllFromCollection.bind(\n\t\t\tthis.documentManager,\n\t\t\tthis.collection,\n\t\t);\n\t\tthis.clone = this.documentManager.clone.bind(\n\t\t\tthis.documentManager,\n\t\t\tthis.collection,\n\t\t);\n\t}\n\n\tprivate serializeIndex = (index?: CollectionFilter) => {\n\t\tif (!index) return '';\n\t\treturn hashObject(index);\n\t};\n\n\tget = (id: string) => {\n\t\tconst key = `get:${this.collection}:${id}`;\n\t\treturn this.cache.getOrSet(\n\t\t\tkey,\n\t\t\t() =>\n\t\t\t\tnew GetQuery<T>({\n\t\t\t\t\tid,\n\t\t\t\t\tcollection: this.collection,\n\t\t\t\t\thydrate: this.hydrate,\n\t\t\t\t\tcontext: this.context,\n\t\t\t\t\tkey,\n\t\t\t\t}),\n\t\t);\n\t};\n\n\tfindOne = ({\n\t\tindex,\n\t\tkey: providedKey,\n\t}: { index?: Filter; key?: string } = {}) => {\n\t\tconst key =\n\t\t\tprovidedKey || `findOne:${this.collection}:${this.serializeIndex(index)}`;\n\t\treturn this.cache.getOrSet(\n\t\t\tkey,\n\t\t\t() =>\n\t\t\t\tnew FindOneQuery<T>({\n\t\t\t\t\tindex,\n\t\t\t\t\tcollection: this.collection,\n\t\t\t\t\thydrate: this.hydrate,\n\t\t\t\t\tcontext: this.context,\n\t\t\t\t\tkey,\n\t\t\t\t}),\n\t\t\t(existing) => {\n\t\t\t\texisting[UPDATE](index);\n\t\t\t},\n\t\t);\n\t};\n\n\tfindAll = ({\n\t\tindex,\n\t\tkey: providedKey,\n\t}: { index?: Filter; key?: string } = {}) => {\n\t\tconst key =\n\t\t\tprovidedKey || `findAll:${this.collection}:${this.serializeIndex(index)}`;\n\t\treturn this.cache.getOrSet(\n\t\t\tkey,\n\t\t\t() =>\n\t\t\t\tnew FindAllQuery<T>({\n\t\t\t\t\tindex,\n\t\t\t\t\tcollection: this.collection,\n\t\t\t\t\thydrate: this.hydrate,\n\t\t\t\t\tcontext: this.context,\n\t\t\t\t\tkey,\n\t\t\t\t}),\n\t\t\t(existing) => {\n\t\t\t\texisting[UPDATE](index);\n\t\t\t},\n\t\t);\n\t};\n\n\tfindPage = ({\n\t\tindex,\n\t\tpageSize,\n\t\tpage,\n\t\tkey: providedKey,\n\t}: {\n\t\tindex?: Filter;\n\t\tpageSize: number;\n\t\tpage: number;\n\t\tkey?: string;\n\t}) => {\n\t\tconst key =\n\t\t\tprovidedKey ||\n\t\t\t`findPage:${this.collection}:${this.serializeIndex(index)}:${pageSize}`;\n\t\treturn this.cache.getOrSet(\n\t\t\tkey,\n\t\t\t() =>\n\t\t\t\tnew FindPageQuery<T>({\n\t\t\t\t\tindex,\n\t\t\t\t\tcollection: this.collection,\n\t\t\t\t\thydrate: this.hydrate,\n\t\t\t\t\tcontext: this.context,\n\t\t\t\t\tkey,\n\t\t\t\t\tpageSize,\n\t\t\t\t\tpage,\n\t\t\t\t}),\n\t\t\t(existing) => {\n\t\t\t\texisting[UPDATE](index);\n\t\t\t},\n\t\t);\n\t};\n\n\tfindAllInfinite = ({\n\t\tindex,\n\t\tpageSize,\n\t\tkey: providedKey,\n\t}: {\n\t\tindex?: Filter;\n\t\tpageSize: number;\n\t\tkey?: string;\n\t}) => {\n\t\tconst key =\n\t\t\tprovidedKey ||\n\t\t\t`findAllInfinite:${this.collection}:${this.serializeIndex(\n\t\t\t\tindex,\n\t\t\t)}:${pageSize}`;\n\t\treturn this.cache.getOrSet(\n\t\t\tkey,\n\t\t\t() =>\n\t\t\t\tnew FindInfiniteQuery<T>({\n\t\t\t\t\tindex,\n\t\t\t\t\tcollection: this.collection,\n\t\t\t\t\thydrate: this.hydrate,\n\t\t\t\t\tcontext: this.context,\n\t\t\t\t\tkey,\n\t\t\t\t\tpageSize,\n\t\t\t\t}),\n\t\t\t(existing) => {\n\t\t\t\texisting[UPDATE](index);\n\t\t\t},\n\t\t);\n\t};\n}\n", "import { Context } from '../context/context.js';\nimport { Disposable } from '../utils/Disposable.js';\nimport { BaseQuery, ON_ALL_UNSUBSCRIBED } from './BaseQuery.js';\n\nexport class QueryCache extends Disposable {\n\tprivate _cache: Map<string, BaseQuery<any>> = new Map();\n\tprivate _evictionTime;\n\tprivate context;\n\t/** A set of query keys to keep alive even if they unsubscribe */\n\tprivate _holds = new Set<string>();\n\n\tconstructor({\n\t\tevictionTime = 5 * 1000,\n\t\tcontext,\n\t}: {\n\t\tevictionTime?: number;\n\t\tcontext: Context;\n\t}) {\n\t\tsuper();\n\n\t\tthis._evictionTime = evictionTime;\n\t\tthis.context = context;\n\t\tthis.addDispose(\n\t\t\tthis.context.internalEvents.subscribe(\n\t\t\t\t'persistenceReset',\n\t\t\t\tthis.forceRefreshAll,\n\t\t\t),\n\t\t);\n\t}\n\n\tget activeKeys() {\n\t\treturn Array.from(this._cache.keys());\n\t}\n\n\tget<T extends BaseQuery<any>>(key: string): T | null {\n\t\treturn (this._cache.get(key) as T) || null;\n\t}\n\n\tset<V extends BaseQuery<any>>(value: V) {\n\t\tthis._cache.set(value.key, value);\n\t\tvalue[ON_ALL_UNSUBSCRIBED](this.enqueueQueryEviction);\n\t\t// immediately enqueue a check to see if this query should be evicted --\n\t\t// this basically gives code X seconds to subscribe to the query before\n\t\t// it gets evicted.\n\t\tthis.enqueueQueryEviction(value);\n\n\t\treturn value;\n\t}\n\n\tgetOrSet<V extends BaseQuery<any>>(\n\t\tkey: string,\n\t\tcreate: () => V,\n\t\tupdate?: (query: V) => void,\n\t) {\n\t\tconst existing = this.get<V>(key);\n\t\tif (existing) {\n\t\t\tupdate?.(existing);\n\t\t\treturn existing;\n\t\t}\n\t\tthis.context.log('debug', 'QueryCache: creating new query', key);\n\t\treturn this.set(create());\n\t}\n\n\tprivate enqueueQueryEviction = (query: BaseQuery<any>) => {\n\t\tsetTimeout(() => {\n\t\t\tif (query.subscribed) return;\n\n\t\t\tif (this._holds.has(query.key)) {\n\t\t\t\tthis.context.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'QueryCache: keepAlive hold on query preserves after unsubscribe',\n\t\t\t\t\tquery.key,\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// double check before evicting... possible the cache\n\t\t\t// got a different version of this query.\n\t\t\tif (this._cache.get(query.key) === query) {\n\t\t\t\tthis._cache.delete(query.key);\n\t\t\t\tthis.context.log('debug', 'QueryCache: evicted query', query.key);\n\t\t\t}\n\t\t}, this._evictionTime);\n\t};\n\n\tdropAll = () => {\n\t\tthis.context.log(\n\t\t\t'debug',\n\t\t\t'QueryCache: drop all',\n\t\t\tthis._cache.size,\n\t\t\t'queries',\n\t\t);\n\t\tthis._cache.forEach((query) => query.dispose());\n\t\tthis._cache.clear();\n\t};\n\n\tforceRefreshAll = () => {\n\t\tthis.context.log(\n\t\t\t'debug',\n\t\t\t'QueryCache: force refresh all',\n\t\t\tthis._cache.size,\n\t\t\t'queries',\n\t\t);\n\t\tthis._cache.forEach((q) => q.execute());\n\t};\n\n\tkeepAlive(key: string) {\n\t\tthis._holds.add(key);\n\t\tthis.context.log('debug', 'QueryCache: keepAlive', key);\n\t}\n\n\tdropKeepAlive(key: string) {\n\t\tthis._holds.delete(key);\n\t\tconst cached = this.get(key);\n\t\tif (!cached) return;\n\t\tif (!cached.subscribed) {\n\t\t\tthis.context.log(\n\t\t\t\t'debug',\n\t\t\t\t'QueryCache: dropKeepAlive on unsubscribed query; queuing eviction',\n\t\t\t\tkey,\n\t\t\t);\n\t\t\tthis.enqueueQueryEviction(cached);\n\t\t}\n\t}\n\n\tget keepAlives() {\n\t\treturn this._holds;\n\t}\n}\n\nexport type PublicQueryCacheAPI = Pick<\n\tQueryCache,\n\t| 'keepAlive'\n\t| 'dropKeepAlive'\n\t| 'keepAlives'\n\t| 'forceRefreshAll'\n\t| 'activeKeys'\n>;\n", "export async function attemptToRegisterBackgroundSync() {\n\ttry {\n\t\tconst status = await navigator.permissions.query({\n\t\t\tname: 'periodic-background-sync' as any,\n\t\t});\n\t\tif (status.state === 'granted') {\n\t\t\t// Periodic background sync can be used.\n\t\t\tconst registration = await navigator.serviceWorker.ready;\n\t\t\tif ('periodicSync' in registration) {\n\t\t\t\ttry {\n\t\t\t\t\tawait (registration.periodicSync as any).register('verdant-sync', {\n\t\t\t\t\t\t// An interval of one day.\n\t\t\t\t\t\tminInterval: 24 * 60 * 60 * 1000,\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Periodic background sync cannot be used.\n\t\t\t\t\tconsole.warn('Failed to register background sync:', error);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Periodic background sync cannot be used.\n\t\t\tconsole.debug('Background sync permission is not granted:', status);\n\t\t}\n\t} catch (error) {\n\t\tconsole.error('Failed to initiate background sync:', error);\n\t}\n}\n", "import { FileData } from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { Disposable } from '../utils/Disposable.js';\nimport { ServerSyncEndpointProvider } from './ServerSyncEndpointProvider.js';\n\nexport interface FileUploadResult {\n\tsuccess: boolean;\n\terror?: string;\n}\n\nexport type FilePullResult =\n\t| {\n\t\t\tsuccess: true;\n\t\t\tdata: FileData;\n\t }\n\t| {\n\t\t\tsuccess: false;\n\t\t\terror?: any;\n\t };\n\nexport class FileSync extends Disposable {\n\tprivate endpointProvider: ServerSyncEndpointProvider;\n\tprivate ctx;\n\n\tconstructor({\n\t\tendpointProvider,\n\t\tctx,\n\t}: {\n\t\tendpointProvider: ServerSyncEndpointProvider;\n\t\tctx: Context;\n\t}) {\n\t\tsuper();\n\t\tthis.endpointProvider = endpointProvider;\n\t\tthis.ctx = ctx;\n\t\tthis.addDispose(\n\t\t\tctx.internalEvents.subscribe('fileAdded', this.onFileAdded),\n\t\t);\n\t}\n\n\tprivate onFileAdded = async (data: FileData) => {\n\t\tif (data.remote) return;\n\t\tthis.ctx.log('debug', 'Uploading file', data.id, data.name);\n\t\ttry {\n\t\t\tawait this.uploadFile(data);\n\t\t} catch (e) {\n\t\t\tthis.ctx.log('error', 'File upload failed', e);\n\t\t}\n\t};\n\n\t/**\n\t * Attempts to upload a file to the sync server. Will be retried\n\t * according to retry config.\n\t */\n\tuploadFile = async (\n\t\tdata: FileData,\n\t\tretries: { max: number; current: number } = { current: 0, max: 3 },\n\t): Promise<FileUploadResult> => {\n\t\tconst file = data.file;\n\n\t\tif (!file) {\n\t\t\tthrow new Error('Cannot upload a non-local file');\n\t\t}\n\n\t\t// multipart upload\n\t\tconst { files: fileEndpoint, token } =\n\t\t\tawait this.endpointProvider.getEndpoints();\n\n\t\tconst formData = new FormData();\n\t\tformData.append('file', file);\n\n\t\ttry {\n\t\t\tconst response = await this.ctx.environment.fetch(\n\t\t\t\tfileEndpoint + `/${data.id}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\tbody: formData,\n\t\t\t\t\tcredentials: 'include',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (response.ok) {\n\t\t\t\tthis.ctx.internalEvents.emit(`fileUploaded:${data.id}`, data);\n\t\t\t\tthis.ctx.internalEvents.emit('fileUploaded', data);\n\t\t\t\tthis.ctx.log('info', 'File upload successful');\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tconst responseText = await response.text();\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'error',\n\t\t\t\t\t'File upload failed',\n\t\t\t\t\tresponse.status,\n\t\t\t\t\tresponseText,\n\t\t\t\t);\n\t\t\t\tif (response.status < 500 || retries.current >= retries.max) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\terror: `Failed to upload file: ${response.status} ${responseText}`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 1000));\n\t\t\t\treturn this.uploadFile(data, {\n\t\t\t\t\tmax: retries.max,\n\t\t\t\t\tcurrent: retries.current + 1,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tthis.ctx.log('error', 'File upload failed', e);\n\t\t\tif (retries.current >= retries.max) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: (e as Error).message,\n\t\t\t\t};\n\t\t\t}\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 1000));\n\t\t\treturn this.uploadFile(data, {\n\t\t\t\tmax: retries.max,\n\t\t\t\tcurrent: retries.current + 1,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Pulls a file from the server by its ID. Will be retried\n\t * according to retry config.\n\t */\n\tgetFile = async (\n\t\tid: string,\n\t\tretries: { current: number; max: number } = { current: 0, max: 3 },\n\t): Promise<FilePullResult> => {\n\t\tconst { files: fileEndpoint, token } =\n\t\t\tawait this.endpointProvider.getEndpoints();\n\n\t\ttry {\n\t\t\tconst response = await this.ctx.environment.fetch(\n\t\t\t\tfileEndpoint + `/${id}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\tcredentials: 'include',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (response.ok) {\n\t\t\t\tconst data = await response.json();\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tdata,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'warn',\n\t\t\t\t\t'File information fetch failed',\n\t\t\t\t\tfileEndpoint + `/${id}`,\n\t\t\t\t\tresponse.status,\n\t\t\t\t\tawait response.text(),\n\t\t\t\t);\n\t\t\t\tif (\n\t\t\t\t\t(response.status < 500 && response.status !== 404) ||\n\t\t\t\t\tretries.current >= retries.max\n\t\t\t\t) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\terror: `Failed to fetch file: ${response.status}`,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 1000));\n\t\t\t\treturn this.getFile(id, {\n\t\t\t\t\tcurrent: retries.current + 1,\n\t\t\t\t\tmax: retries.max,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'warn',\n\t\t\t\t'File information fetch failed',\n\t\t\t\t`${fileEndpoint}/${id}`,\n\t\t\t\te,\n\t\t\t);\n\t\t\tif (retries.current >= retries.max) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: (e as Error).message,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 1000));\n\t\t\treturn this.getFile(id, {\n\t\t\t\tcurrent: retries.current + 1,\n\t\t\t\tmax: retries.max,\n\t\t\t});\n\t\t}\n\t};\n}\n", "import {\n\tBatch,\n\tBatcher,\n\tEventSubscriber,\n\tServerMessage,\n\tVerdantInternalPresence,\n\tinitialInternalPresence,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport type { UserInfo } from '../index.js';\nimport { LocalReplicaInfo } from '../persistence/interfaces.js';\n\nexport const HANDLE_MESSAGE = Symbol('handleMessage');\n\nexport class PresenceManager<\n\tProfile = any,\n\tPresence = any,\n> extends EventSubscriber<{\n\t/**\n\t * Fired when a particular peer's presence changes\n\t */\n\tpeerChanged: (userId: string, presence: UserInfo<Profile, Presence>) => void;\n\t/**\n\t * Fired immediately when a change to local presence is made. This change may not\n\t * yet have been sent to the server (see: \"update\" event)\n\t */\n\tselfChanged: (presence: UserInfo<Profile, Presence>) => void;\n\t/** Fired when any number of peer presences have changed */\n\tpeersChanged: (peers: Record<string, UserInfo<Profile, Presence>>) => void;\n\t/** Fired when a peer presence goes offline */\n\tpeerLeft: (userId: string, lastPresence: UserInfo<Profile, Presence>) => void;\n\t/** Fired after local presence changes are flushed to the server. */\n\tupdate: (data: {\n\t\tpresence?: Presence;\n\t\tinternal?: VerdantInternalPresence;\n\t}) => void;\n\tload: () => void;\n\t/** Fired on any change to a peer or the local user */\n\tchange: () => void;\n}> {\n\tprivate _peers = {} as Record<string, UserInfo<Profile, Presence>>;\n\tprivate _self = { profile: {} } as UserInfo<Profile, Presence>;\n\t// keep track of own replica IDs - applications may care if we're \"alone\" but with multiple devices.\n\tprivate _selfReplicaIds = new Set<string>();\n\tprivate _peerIds = new Array<string>();\n\tprivate _updateBatcher;\n\tprivate _updateBatch: Batch<{\n\t\tpresence?: Partial<Presence>;\n\t\tinternal?: Partial<VerdantInternalPresence>;\n\t}>;\n\n\tget self() {\n\t\treturn this._self;\n\t}\n\n\tget peers() {\n\t\treturn this._peers;\n\t}\n\n\tget peerIds() {\n\t\treturn this._peerIds;\n\t}\n\n\tget everyone() {\n\t\tconst everyone = { ...this._peers };\n\t\teveryone[this.self.id] = this.self;\n\t\treturn everyone;\n\t}\n\n\tget selfReplicaIds() {\n\t\treturn this._selfReplicaIds;\n\t}\n\n\tconstructor({\n\t\tinitialPresence,\n\t\tupdateBatchTimeout = 200,\n\t\tdefaultProfile,\n\t\tctx,\n\t}: {\n\t\tinitialPresence: Presence;\n\t\tdefaultProfile: Profile;\n\t\tupdateBatchTimeout?: number;\n\t\tctx: Context;\n\t}) {\n\t\tsuper();\n\t\tthis.self.presence = initialPresence;\n\t\tthis.self.profile = defaultProfile;\n\t\tthis.self.internal = initialInternalPresence;\n\t\tthis.self.id = '';\n\t\tthis.self.replicaId = '';\n\n\t\t// set the local replica ID as soon as it's loaded\n\t\tctx.waitForInitialization\n\t\t\t.then(() => ctx.meta)\n\t\t\t.then((meta) => meta.getLocalReplica())\n\t\t\t.then((info) => {\n\t\t\t\tthis.self.replicaId = info.id;\n\t\t\t});\n\n\t\tthis._updateBatcher = new Batcher(this.flushPresenceUpdates);\n\t\tthis._updateBatch = this._updateBatcher.add({\n\t\t\tmax: 25,\n\t\t\ttimeout: updateBatchTimeout,\n\t\t\titems: [],\n\t\t\tkey: 'default',\n\t\t});\n\t}\n\n\t/**\n\t * Decides if an update is for the local user or not. Even if it's a different replica\n\t * than the local one.\n\t *\n\t * If the replicaId matches, we use that first - we may not know the local replica's User ID yet,\n\t * e.g. on the first presence update.\n\t *\n\t * Otherwise, match the user ID to our local copy.\n\t */\n\tprivate isSelf = (\n\t\tlocalReplicaInfo: LocalReplicaInfo,\n\t\tuserInfo: UserInfo<Profile, Presence>,\n\t) => {\n\t\treturn (\n\t\t\tlocalReplicaInfo.id === userInfo.replicaId ||\n\t\t\tthis._selfReplicaIds.has(userInfo.replicaId) ||\n\t\t\tthis._self.id === userInfo.id\n\t\t);\n\t};\n\n\t[HANDLE_MESSAGE] = async (\n\t\tlocalReplicaInfo: LocalReplicaInfo,\n\t\tmessage: ServerMessage,\n\t) => {\n\t\tlet peersChanged = false;\n\t\tlet selfChanged = false;\n\t\tconst peerIdsSet = new Set<string>(this.peerIds);\n\n\t\tif (message.type === 'presence-changed') {\n\t\t\tif (this.isSelf(localReplicaInfo, message.userInfo)) {\n\t\t\t\tthis._self = message.userInfo;\n\t\t\t\tthis._selfReplicaIds.add(message.userInfo.replicaId);\n\t\t\t\tselfChanged = true;\n\t\t\t\tthis.emit('selfChanged', message.userInfo);\n\t\t\t} else {\n\t\t\t\tpeerIdsSet.add(message.userInfo.id);\n\t\t\t\tthis._peers[message.userInfo.id] = message.userInfo;\n\t\t\t\tpeersChanged = true;\n\t\t\t\tthis.emit('peerChanged', message.userInfo.id, message.userInfo);\n\t\t\t}\n\t\t} else if (message.type === 'sync-resp') {\n\t\t\t// reset to provided presence data, which includes all peers.\n\t\t\tthis._peers = {};\n\t\t\tpeerIdsSet.clear();\n\n\t\t\tfor (const [id, userInfo] of Object.entries(message.peerPresence)) {\n\t\t\t\tif (this.isSelf(localReplicaInfo, userInfo)) {\n\t\t\t\t\tthis._self = userInfo;\n\t\t\t\t\tthis._selfReplicaIds.add(userInfo.replicaId);\n\t\t\t\t\tselfChanged = true;\n\t\t\t\t\tthis.emit('selfChanged', userInfo);\n\t\t\t\t} else {\n\t\t\t\t\tpeersChanged = true;\n\t\t\t\t\tpeerIdsSet.add(id);\n\t\t\t\t\tthis._peers[id] = userInfo;\n\t\t\t\t\tthis.emit('peerChanged', id, userInfo);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (message.type === 'presence-offline') {\n\t\t\tpeerIdsSet.delete(message.userId);\n\t\t\tthis._selfReplicaIds.delete(message.replicaId);\n\t\t\tconst lastPresence = this._peers[message.userId];\n\t\t\tdelete this._peers[message.userId];\n\t\t\tpeersChanged = true;\n\t\t\tthis.emit('peerLeft', message.userId, lastPresence);\n\t\t}\n\t\tif (peersChanged) {\n\t\t\t// important that this stays sorted to keep stable order, don't want\n\t\t\t// peers swapping around.\n\t\t\tthis._peerIds = Array.from(peerIdsSet).sort();\n\t\t\tthis.emit('peersChanged', this._peers);\n\t\t}\n\t\tif (peersChanged || selfChanged) {\n\t\t\tthis.emit('change');\n\t\t}\n\t};\n\n\tupdate = async (presence: Partial<Presence>) => {\n\t\tthis._updateBatch.update({\n\t\t\titems: [{ presence }],\n\t\t});\n\t\t// proactively update the local presence\n\t\tthis.self.presence = { ...this.self.presence, ...presence };\n\t\tthis.emit('selfChanged', this.self);\n\t\tthis.emit('change');\n\t};\n\n\tflushPresenceUpdates = (\n\t\tpresenceUpdates: {\n\t\t\tpresence?: Partial<Presence>;\n\t\t\tinternal?: Partial<VerdantInternalPresence>;\n\t\t}[],\n\t) => {\n\t\tconst data = {\n\t\t\tpresence: this.self.presence,\n\t\t\tinternal: this.self.internal,\n\t\t};\n\t\tfor (const update of presenceUpdates) {\n\t\t\tif (update.presence) {\n\t\t\t\tObject.assign(data.presence as any, update.presence);\n\t\t\t}\n\t\t\tif (update.internal) {\n\t\t\t\tObject.assign(data.internal, update.internal);\n\t\t\t}\n\t\t}\n\t\tthis.emit('update', data);\n\t};\n\n\tsetViewId = (viewId: string | undefined) => {\n\t\tthis._updateBatch.update({\n\t\t\titems: [{ internal: { viewId } }],\n\t\t});\n\t\tthis.self.internal.viewId = viewId;\n\t\tthis.emit('selfChanged', this.self);\n\t\tthis.emit('change');\n\t};\n\n\tsetFieldId = (fieldId: string | undefined, timestamp = Date.now()) => {\n\t\tthis._updateBatch.update({\n\t\t\titems: [\n\t\t\t\t{ internal: { lastFieldId: fieldId, lastFieldTimestamp: timestamp } },\n\t\t\t],\n\t\t});\n\t\tthis.self.internal.lastFieldId = fieldId;\n\t\tthis.emit('selfChanged', this.self);\n\t\tthis.emit('change');\n\t};\n\n\t/**\n\t * Get all peers that are in the same view as the local user.\n\t */\n\tgetViewPeers = () => {\n\t\treturn (\n\t\t\tthis._peerIds\n\t\t\t\t.map((id) => this._peers[id])\n\t\t\t\t// undefined view matches all peers. otherwise,\n\t\t\t\t// filter to only those in the same view.\n\t\t\t\t.filter(\n\t\t\t\t\t(peer) =>\n\t\t\t\t\t\tthis.self.internal.viewId === undefined ||\n\t\t\t\t\t\tpeer.internal.viewId === this.self.internal.viewId,\n\t\t\t\t)\n\t\t);\n\t};\n\n\t/**\n\t * Get all peers that have interacted with the specified\n\t * field most recently.\n\t */\n\tgetFieldPeers = (fieldId: string, expirationPeriod = 60 * 1000) => {\n\t\treturn this._peerIds\n\t\t\t.map((id) => this._peers[id])\n\t\t\t.filter(\n\t\t\t\t(peer) =>\n\t\t\t\t\tpeer.internal.lastFieldId === fieldId &&\n\t\t\t\t\tDate.now() - peer.internal.lastFieldTimestamp! < expirationPeriod,\n\t\t\t);\n\t};\n}\n", "import { EventSubscriber } from '@verdant-web/common';\n\nexport class Heartbeat extends EventSubscriber<{\n\tmissed: () => void;\n\tbeat: () => void;\n}> {\n\tprivate _interval: number;\n\tprivate deadlineLength: number;\n\tprivate nextBeat: NodeJS.Timeout | null = null;\n\tprivate deadline: NodeJS.Timeout | null = null;\n\n\tget interval() {\n\t\treturn this._interval;\n\t}\n\n\tconstructor({\n\t\tinterval = 15 * 1000,\n\t\tdeadlineLength = 3 * 1000,\n\t\trestartOnTabFocus = true,\n\t}: {\n\t\tinterval?: number;\n\t\tdeadlineLength?: number;\n\t\trestartOnTabFocus?: boolean;\n\t} = {}) {\n\t\tsuper();\n\t\tthis._interval = interval;\n\t\tthis.deadlineLength = deadlineLength;\n\t\tif (typeof window !== 'undefined' && restartOnTabFocus) {\n\t\t\twindow.addEventListener('pageshow', () => this.start(true));\n\t\t\tdocument.addEventListener('visibilitychange', () => {\n\t\t\t\tif (document.visibilityState === 'visible') {\n\t\t\t\t\tthis.start(true);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tkeepAlive = () => {\n\t\tif (this.deadline) {\n\t\t\tclearTimeout(this.deadline);\n\t\t\tthis.deadline = null;\n\t\t\tthis.start();\n\t\t}\n\t};\n\n\tstart = (immediate = false) => {\n\t\tthis.stop();\n\t\tif (immediate) {\n\t\t\tthis.beat();\n\t\t} else {\n\t\t\tthis.nextBeat = setTimeout(this.beat, this._interval);\n\t\t}\n\t};\n\n\tstop = () => {\n\t\tif (this.nextBeat) {\n\t\t\tclearTimeout(this.nextBeat);\n\t\t\tthis.nextBeat = null;\n\t\t}\n\t\tif (this.deadline) {\n\t\t\tclearTimeout(this.deadline);\n\t\t\tthis.deadline = null;\n\t\t}\n\t};\n\n\tprivate beat = async () => {\n\t\tthis.emit('beat');\n\t\tthis.deadline = setTimeout(this.onDeadline, this.deadlineLength);\n\t};\n\n\tprivate onDeadline = () => {\n\t\tthis.deadline = null;\n\t\tthis.emit('missed');\n\t};\n\n\t/**\n\t * Only takes affect after the next beat\n\t */\n\tsetInterval = (interval: number) => {\n\t\tthis._interval = interval;\n\t};\n}\n", "import {\n\tClientMessage,\n\tEventSubscriber,\n\tPresenceUpdateMessage,\n\tServerMessage,\n\tVerdantErrorCode,\n\tisVerdantErrorResponse,\n\tthrottle,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { Heartbeat } from './Heartbeat.js';\nimport { PresenceManager } from './PresenceManager.js';\nimport { ServerSyncEndpointProvider } from './ServerSyncEndpointProvider.js';\nimport { SyncTransport, SyncTransportEvents } from './Sync.js';\n\nexport class PushPullSync\n\textends EventSubscriber<SyncTransportEvents>\n\timplements SyncTransport\n{\n\treadonly presence: PresenceManager;\n\tprivate endpointProvider;\n\tprivate heartbeat;\n\tprivate get fetch() {\n\t\treturn this.ctx.environment.fetch;\n\t}\n\n\treadonly mode = 'pull';\n\tprivate ctx;\n\n\tprivate _isConnected = false;\n\tprivate _status: 'active' | 'paused' = 'paused';\n\tprivate _hasSynced = false;\n\n\tconstructor({\n\t\tendpointProvider,\n\t\tpresence,\n\t\tinterval = 15 * 1000,\n\t\tctx,\n\t}: {\n\t\tendpointProvider: ServerSyncEndpointProvider;\n\t\tpresence: PresenceManager;\n\t\tinterval?: number;\n\t\tctx: Context;\n\t}) {\n\t\tsuper();\n\t\tthis.ctx = ctx;\n\t\tthis.presence = presence;\n\t\tthis.endpointProvider = endpointProvider;\n\n\t\tthis.heartbeat = new Heartbeat({\n\t\t\tinterval,\n\t\t});\n\t\tthis.heartbeat.subscribe('beat', this.onHeartbeat);\n\t\tthis.heartbeat.subscribe('missed', this.onHeartbeatMissed);\n\t}\n\n\tsetInterval = (interval: number) => {\n\t\tthis.heartbeat.setInterval(interval);\n\t};\n\n\tget interval() {\n\t\treturn this.heartbeat.interval;\n\t}\n\n\tget hasSynced() {\n\t\treturn this._hasSynced;\n\t}\n\n\tprivate sendRequest = async (messages: ClientMessage[]) => {\n\t\tthis.ctx.log('debug', 'Sending sync request', messages);\n\t\ttry {\n\t\t\tconst { http: host, token } = await this.endpointProvider.getEndpoints();\n\t\t\tconst response = await this.fetch(host, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tmessages,\n\t\t\t\t}),\n\t\t\t\tcredentials: 'include',\n\t\t\t});\n\t\t\tif (response.ok) {\n\t\t\t\tthis.heartbeat.keepAlive();\n\t\t\t\tconst json = (await response.json()) as {\n\t\t\t\t\tmessages: ServerMessage[];\n\t\t\t\t};\n\t\t\t\t// for (const message of json.messages) {\n\t\t\t\t// \tthis.handleServerMessage(message);\n\t\t\t\t// }\n\t\t\t\tconst handlePromise = Promise.all(\n\t\t\t\t\tjson.messages.map(this.handleServerMessage),\n\t\t\t\t);\n\t\t\t\tif (!this._isConnected) {\n\t\t\t\t\tthis._isConnected = true;\n\t\t\t\t\tthis.emit('onlineChange', true);\n\t\t\t\t}\n\t\t\t\tawait handlePromise;\n\t\t\t} else {\n\t\t\t\tthis.ctx.log('error', 'Sync request failed', host, response.status);\n\n\t\t\t\tif (this._isConnected) {\n\t\t\t\t\tthis._isConnected = false;\n\t\t\t\t\tthis.emit('onlineChange', false);\n\t\t\t\t}\n\n\t\t\t\tconst json = await response.json();\n\t\t\t\tif (isVerdantErrorResponse(json)) {\n\t\t\t\t\t// token expired... retry again later after clearing it\n\t\t\t\t\tif (json.code === VerdantErrorCode.TokenExpired) {\n\t\t\t\t\t\tthis.endpointProvider.clearCache();\n\t\t\t\t\t\tthis.heartbeat.keepAlive();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.ctx.log('error', 'Server error', json);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// only keep trying if the error was not 4xx\n\t\t\t\tif (response.status >= 500) {\n\t\t\t\t\tthis.heartbeat.keepAlive();\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (this._isConnected) {\n\t\t\t\tthis._isConnected = false;\n\t\t\t\tthis.emit('onlineChange', false);\n\t\t\t}\n\t\t\tthis.ctx.log('error', error);\n\n\t\t\tthis.heartbeat.keepAlive();\n\t\t}\n\t};\n\n\tprivate handleServerMessage = async (message: ServerMessage) => {\n\t\tif (message.type === 'sync-resp') {\n\t\t\t// we need to ack the nonce to confirm that we received the sync-resp\n\t\t\t// but we can go ahead and preemptively allow ops to be sent\n\t\t\tthis._hasSynced = true;\n\t\t\tif (message.ackThisNonce) {\n\t\t\t\tthis.ctx.log('debug', 'Sending sync ack', message.ackThisNonce);\n\t\t\t\tawait this.sendRequest([\n\t\t\t\t\tawait (\n\t\t\t\t\t\tawait this.ctx.meta\n\t\t\t\t\t).messageCreator.createAck(message.ackThisNonce),\n\t\t\t\t]);\n\t\t\t}\n\t\t}\n\t\tthis.emit('message', message);\n\t};\n\n\t// reduce rate of presence messages sent; each one would trigger an HTTP\n\t// request, which is not ideal if presence is updating rapidly.\n\tthrottledPresenceUpdate = throttle((message: PresenceUpdateMessage) => {\n\t\tthis.sendRequest([message]);\n\t}, 3000);\n\n\tsend = (message: ClientMessage) => {\n\t\tif (this.status !== 'active') {\n\t\t\tthis.ctx.log(\n\t\t\t\t'warn',\n\t\t\t\t'Attempted to send message while sync is not active',\n\t\t\t\tmessage,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\t// only certain messages are sent for pull-based sync.\n\t\tswitch (message.type) {\n\t\t\tcase 'presence-update':\n\t\t\t\treturn this.throttledPresenceUpdate(message);\n\t\t\tcase 'sync':\n\t\t\tcase 'heartbeat':\n\t\t\t\treturn this.sendRequest([message]);\n\t\t\tcase 'op':\n\t\t\t\tif (this._hasSynced) {\n\t\t\t\t\treturn this.sendRequest([message]);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\tstart = async () => {\n\t\tif (this.status === 'active') {\n\t\t\treturn;\n\t\t}\n\t\tthis.ctx.log('debug', 'Starting push-pull sync');\n\t\tawait this.endpointProvider.getEndpoints();\n\t\tthis.heartbeat.start(true);\n\t\tthis._status = 'active';\n\t};\n\tstop(): void {\n\t\tthis.ctx.log('debug', 'Stopping push-pull sync');\n\t\tthis.heartbeat.stop();\n\t\tthis._status = 'paused';\n\t}\n\n\tdestroy = () => {\n\t\tthis.dispose();\n\t\tthis.stop();\n\t};\n\treconnect(): void {\n\t\tthis.heartbeat.start(true);\n\t}\n\n\tignoreIncoming(): void {\n\t\tthis.stop();\n\t}\n\n\t// on a heartbeat, do a sync\n\tprivate onHeartbeat = async () => {\n\t\t// for HTTP sync we send presence first, so that the sync-resp message\n\t\t// will include the client's own presence info and fill in missing profile\n\t\t// data on the first request. otherwise it would have to wait for the second.\n\t\tthis.sendRequest([\n\t\t\tawait (\n\t\t\t\tawait this.ctx.meta\n\t\t\t).messageCreator.createPresenceUpdate(this.presence.self),\n\t\t\tawait (await this.ctx.meta).messageCreator.createSyncStep1(),\n\t\t]);\n\t};\n\n\t// if the server fails to respond in a certain amount of time, we assume\n\t// the connection is lost and go offline.\n\tprivate onHeartbeatMissed = async () => {\n\t\tthis.emit('onlineChange', false);\n\t\tthis.ctx.log('warn', 'Missed heartbeat');\n\t\tthis._isConnected = false;\n\t};\n\n\tsyncOnce = async () => {\n\t\tawait this.sendRequest([\n\t\t\tawait (await this.ctx.meta).messageCreator.createSyncStep1(),\n\t\t]);\n\t};\n\n\tget isConnected(): boolean {\n\t\treturn this._isConnected;\n\t}\n\tget status() {\n\t\treturn this._status;\n\t}\n}\n", "/**\n * The code was extracted from:\n * https://github.com/davidchambers/Base64.js\n */\n\nvar chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\n\nfunction InvalidCharacterError(message) {\n this.message = message;\n}\n\nInvalidCharacterError.prototype = new Error();\nInvalidCharacterError.prototype.name = \"InvalidCharacterError\";\n\nfunction polyfill(input) {\n var str = String(input).replace(/=+$/, \"\");\n if (str.length % 4 == 1) {\n throw new InvalidCharacterError(\n \"'atob' failed: The string to be decoded is not correctly encoded.\"\n );\n }\n for (\n // initialize result and counters\n var bc = 0, bs, buffer, idx = 0, output = \"\";\n // get next character\n (buffer = str.charAt(idx++));\n // character found in table? initialize bit storage and add its ascii value;\n ~buffer &&\n ((bs = bc % 4 ? bs * 64 + buffer : buffer),\n // and if not first of each 4 characters,\n // convert the first 8 bits to one ascii character\n bc++ % 4) ?\n (output += String.fromCharCode(255 & (bs >> ((-2 * bc) & 6)))) :\n 0\n ) {\n // try to find character in table (0-63, not found => -1)\n buffer = chars.indexOf(buffer);\n }\n return output;\n}\n\nexport default (typeof window !== \"undefined\" &&\n window.atob &&\n window.atob.bind(window)) ||\npolyfill;", "import atob from \"./atob\";\n\nfunction b64DecodeUnicode(str) {\n return decodeURIComponent(\n atob(str).replace(/(.)/g, function(m, p) {\n var code = p.charCodeAt(0).toString(16).toUpperCase();\n if (code.length < 2) {\n code = \"0\" + code;\n }\n return \"%\" + code;\n })\n );\n}\n\nexport default function(str) {\n var output = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n switch (output.length % 4) {\n case 0:\n break;\n case 2:\n output += \"==\";\n break;\n case 3:\n output += \"=\";\n break;\n default:\n throw \"Illegal base64url string!\";\n }\n\n try {\n return b64DecodeUnicode(output);\n } catch (err) {\n return atob(output);\n }\n}", "\"use strict\";\n\nimport base64_url_decode from \"./base64_url_decode\";\n\nexport function InvalidTokenError(message) {\n this.message = message;\n}\n\nInvalidTokenError.prototype = new Error();\nInvalidTokenError.prototype.name = \"InvalidTokenError\";\n\nexport default function(token, options) {\n if (typeof token !== \"string\") {\n throw new InvalidTokenError(\"Invalid token specified\");\n }\n\n options = options || {};\n var pos = options.header === true ? 0 : 1;\n try {\n return JSON.parse(base64_url_decode(token.split(\".\")[pos]));\n } catch (e) {\n throw new InvalidTokenError(\"Invalid token specified: \" + e.message);\n }\n}", "import { assert, ReplicaType } from '@verdant-web/common';\nimport { default as jwtDecode } from 'jwt-decode';\nimport { Context } from '../internal.js';\n\nexport interface ServerSyncEndpointProviderConfig {\n\t/**\n\t * The location of the endpoint used to retrieve an\n\t * authorization token for the client.\n\t */\n\tauthEndpoint?: string;\n\t/**\n\t * A custom function to retrieve authorization\n\t * data. Use whatever fetching mechanism you want.\n\t */\n\tfetchAuth?: () => Promise<{\n\t\taccessToken: string;\n\t}>;\n}\n\nexport interface SyncTokenInfo {\n\turl: string;\n\tfileUrl: string;\n\ttype: ReplicaType;\n\tuserId: string;\n\tlibraryId: string;\n\trole?: string;\n}\n\nexport class ServerSyncEndpointProvider {\n\tprivate cached = null as {\n\t\thttp: string;\n\t\twebsocket: string;\n\t\tfiles: string;\n\t\ttoken: string;\n\t} | null;\n\ttokenInfo: SyncTokenInfo | null = null;\n\n\tget type() {\n\t\treturn this.tokenInfo?.type ?? ReplicaType.Realtime;\n\t}\n\n\tconstructor(\n\t\tprivate config: ServerSyncEndpointProviderConfig,\n\t\tprivate ctx: Context,\n\t) {\n\t\tif (!config.authEndpoint && !config.fetchAuth) {\n\t\t\tthrow new Error(\n\t\t\t\t'Either authEndpoint or fetchAuth must be provided to ServerSyncEndpointProvider',\n\t\t\t);\n\t\t}\n\t}\n\n\tgetEndpoints = async () => {\n\t\tif (this.cached) {\n\t\t\treturn this.cached;\n\t\t}\n\n\t\tlet result: { accessToken: string };\n\t\tif (this.config.fetchAuth) {\n\t\t\tresult = await this.config.fetchAuth();\n\t\t} else {\n\t\t\tconst fetchImpl = this.ctx.environment.fetch;\n\t\t\tresult = await fetchImpl(this.config.authEndpoint!, {\n\t\t\t\tcredentials: 'include',\n\t\t\t}).then((res) => {\n\t\t\t\tif (!res.ok) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Auth endpoint returned non-200 response: ${res.status}`,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\treturn res.json();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tassert(result.accessToken, 'No access token provided from auth endpoint');\n\t\tconst decoded = (jwtDecode as any)(result.accessToken);\n\t\tassert(decoded.url, 'No sync endpoint provided from auth endpoint');\n\t\tassert(\n\t\t\tdecoded.type !== undefined,\n\t\t\t'No replica type provided from auth endpoint',\n\t\t);\n\t\tthis.tokenInfo = {\n\t\t\tuserId: decoded.sub,\n\t\t\tlibraryId: decoded.lib,\n\t\t\turl: decoded.url,\n\t\t\tfileUrl: decoded.file,\n\t\t\trole: decoded.role,\n\t\t\ttype: parseInt(decoded.type + '') as ReplicaType,\n\t\t};\n\t\tconst url = new URL(decoded.url);\n\t\turl.protocol = url.protocol.replace('ws', 'http');\n\t\tconst httpEndpoint = url.toString();\n\t\turl.protocol = url.protocol.replace('http', 'ws');\n\t\tconst websocketEndpoint = url.toString();\n\t\tlet fileEndpoint: string = decoded.file;\n\t\tif (!fileEndpoint) {\n\t\t\t// default to http endpoint + '/files';\n\t\t\tconst fileUrl = new URL(httpEndpoint);\n\t\t\tfileUrl.pathname = fileUrl.pathname + '/files';\n\t\t\tfileEndpoint = fileUrl.toString();\n\t\t}\n\t\tthis.cached = {\n\t\t\thttp: httpEndpoint,\n\t\t\twebsocket: websocketEndpoint,\n\t\t\tfiles: fileEndpoint,\n\t\t\ttoken: result.accessToken,\n\t\t};\n\t\treturn this.cached;\n\t};\n\n\tclearCache = () => {\n\t\tthis.cached = null;\n\t};\n}\n", "import { EventSubscriber } from '@verdant-web/common';\n\nexport class BackoffScheduler extends EventSubscriber<{\n\ttrigger: () => void;\n}> {\n\tprivate readonly backoff: Backoff;\n\tprivate timer: NodeJS.Timeout | null = null;\n\tprivate isScheduled = false;\n\n\tconstructor(backoff: Backoff) {\n\t\tsuper();\n\t\tthis.backoff = backoff;\n\t}\n\n\tnext = () => {\n\t\tif (!this.isScheduled) {\n\t\t\tthis.isScheduled = true;\n\t\t\tthis.timer = setTimeout(() => {\n\t\t\t\tthis.emit('trigger');\n\t\t\t\tthis.isScheduled = false;\n\t\t\t\tthis.backoff.next();\n\t\t\t}, this.backoff.current);\n\t\t}\n\t};\n\n\treset = () => {\n\t\tthis.backoff.reset();\n\t\tif (this.timer) {\n\t\t\tclearTimeout(this.timer);\n\t\t\tthis.timer = null;\n\t\t}\n\t};\n}\n\nexport class Backoff {\n\tcurrent = 0;\n\tprivate readonly max: number;\n\tprivate readonly factor: number;\n\n\tconstructor(initial: number, max: number, factor: number) {\n\t\tthis.current = initial;\n\t\tthis.max = max;\n\t\tthis.factor = factor;\n\t}\n\n\tnext = () => {\n\t\tthis.current = Math.min(this.max, Math.max(1, this.current) * this.factor);\n\t};\n\n\treset = () => {\n\t\tthis.current = 0;\n\t};\n}\n", "import {\n\tClientMessage,\n\tEventSubscriber,\n\tServerMessage,\n} from '@verdant-web/common';\nimport { Backoff, BackoffScheduler } from '../BackoffScheduler.js';\nimport { Context } from '../context/context.js';\nimport { Heartbeat } from './Heartbeat.js';\nimport { PresenceManager } from './PresenceManager.js';\nimport { ServerSyncEndpointProvider } from './ServerSyncEndpointProvider.js';\nimport { SyncTransport, SyncTransportEvents } from './Sync.js';\n\nexport class WebSocketSync\n\textends EventSubscriber<SyncTransportEvents>\n\timplements SyncTransport\n{\n\treadonly presence: PresenceManager;\n\tprivate socket: WebSocket | null = null;\n\t// messages awaiting websocket connection to send\n\tprivate connectQueue: ClientMessage[] = [];\n\t// messages awaiting sync response to send\n\tprivate syncQueue: ClientMessage[] = [];\n\t// messages waiting for sync to finish\n\tprivate incomingQueue: ServerMessage[] = [];\n\tprivate endpointProvider;\n\tprivate _status: 'active' | 'paused' = 'paused';\n\tprivate synced = false;\n\tprivate hasStartedSync = false;\n\tprivate _ignoreIncoming = false;\n\n\treadonly mode = 'realtime';\n\tprivate ctx: Context;\n\n\tprivate heartbeat = new Heartbeat();\n\n\tprivate reconnectScheduler = new BackoffScheduler(\n\t\tnew Backoff(2_000, 60_000, 1.5),\n\t);\n\n\tconstructor({\n\t\tendpointProvider,\n\t\tctx,\n\t\tpresence,\n\t}: {\n\t\tendpointProvider: ServerSyncEndpointProvider;\n\t\tctx: Context;\n\t\tpresence: PresenceManager;\n\t}) {\n\t\tsuper();\n\t\tthis.ctx = ctx;\n\t\tthis.endpointProvider = endpointProvider;\n\t\tthis.presence = presence;\n\n\t\tthis.reconnectScheduler.subscribe('trigger', this.initializeSocket);\n\t\tthis.heartbeat.subscribe('beat', this.sendHeartbeat);\n\t\twindow.addEventListener('beforeunload', () => {\n\t\t\treturn this.sendDisconnecting();\n\t\t});\n\t}\n\n\tget hasSynced() {\n\t\treturn this.synced;\n\t}\n\n\tprivate onOpen = () => {\n\t\tif (!this.socket) {\n\t\t\tthrow new Error('Invalid sync state: online but socket is null');\n\t\t}\n\t\tthis.synced = false;\n\t\tif (this.connectQueue.length) {\n\t\t\tfor (const msg of this.connectQueue) {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'Sending queued message',\n\t\t\t\t\tJSON.stringify(msg, null, 2),\n\t\t\t\t);\n\t\t\t\tthis.socket.send(JSON.stringify(msg));\n\t\t\t}\n\t\t\tthis.connectQueue = [];\n\t\t}\n\t\tthis.ctx.log('debug', 'Sync connected');\n\t\tthis.onOnlineChange(true);\n\t};\n\n\tprivate onOnlineChange = async (online: boolean) => {\n\t\tthis.ctx.log('info', 'Socket online change', online);\n\t\tif (this.disposed) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.ctx.closing) return;\n\t\tif (!online) {\n\t\t\tthis.hasStartedSync = false;\n\t\t\tthis.synced = false;\n\t\t\tthis.heartbeat.stop();\n\t\t} else {\n\t\t\tthis.ctx.log('debug', 'Starting sync');\n\t\t\tthis.hasStartedSync = true;\n\t\t\tthis.synced = false;\n\t\t\tconst meta = await this.ctx.meta;\n\t\t\tthis.ctx.log('debug', 'HERE');\n\t\t\tthis.send(\n\t\t\t\tawait meta.messageCreator.createPresenceUpdate(this.presence.self),\n\t\t\t);\n\t\t\tthis.send(await meta.messageCreator.createSyncStep1());\n\t\t\tthis.heartbeat.start();\n\t\t}\n\t\tthis.emit('onlineChange', online);\n\t};\n\n\tprivate onMessage = async (event: MessageEvent) => {\n\t\tthis.reconnectScheduler.reset();\n\t\tif (this._ignoreIncoming) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'warn',\n\t\t\t\t'Ignoring incoming message (ignore incoming flag set)',\n\t\t\t\tevent.data,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst message = JSON.parse(event.data) as ServerMessage;\n\t\tthis.ctx.log('debug', 'Received', message.type, 'message');\n\t\tswitch (message.type) {\n\t\t\tcase 'sync-resp':\n\t\t\t\tif (message.ackThisNonce) {\n\t\t\t\t\t// we need to send the ack to confirm we got the response\n\t\t\t\t\tthis.send(\n\t\t\t\t\t\tawait (\n\t\t\t\t\t\t\tawait this.ctx.meta\n\t\t\t\t\t\t).messageCreator.createAck(message.ackThisNonce),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthis.hasStartedSync = true;\n\t\t\t\tthis.synced = true;\n\t\t\t\tif (this.syncQueue.length) {\n\t\t\t\t\tif (message.overwriteLocalData) {\n\t\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t\t'warn',\n\t\t\t\t\t\t\t'Overwriting local data - dropping outgoing message queue',\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.syncQueue = [];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor (const msg of this.syncQueue) {\n\t\t\t\t\t\t\tthis.send(msg);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.syncQueue = [];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.emit('message', message);\n\t\t\t\tif (this.incomingQueue.length) {\n\t\t\t\t\tfor (const msg of this.incomingQueue) {\n\t\t\t\t\t\tthis.emit('message', msg);\n\t\t\t\t\t}\n\t\t\t\t\tthis.incomingQueue = [];\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'need-since':\n\t\t\tcase 'presence-changed':\n\t\t\tcase 'presence-offline':\n\t\t\t\tthis.emit('message', message);\n\t\t\t\tbreak;\n\t\t\tcase 'op-re':\n\t\t\t\tif (!this.synced) {\n\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t'debug',\n\t\t\t\t\t\t`Enqueueing op-re message because sync hasn't finished yet`,\n\t\t\t\t\t\tmessage,\n\t\t\t\t\t);\n\t\t\t\t\tthis.incomingQueue.push(message);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tthis.emit('message', message);\n\t\t\t\tbreak;\n\t\t\tcase 'heartbeat-response':\n\t\t\t\tthis.heartbeat.keepAlive();\n\t\t\t\tthis.emit('message', message);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif (this.synced) {\n\t\t\t\t\tthis.emit('message', message);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\tprivate onError = (event: Event) => {\n\t\tthis.ctx.log('error', 'Sync socket error', event, event.target);\n\t\tif (this.disposed) return;\n\t\t// this could be an auth error which requires us to get a new token\n\t\t// so clearing the endpoint cache to force a refresh of the token too\n\t\tthis.endpointProvider.clearCache();\n\t\tthis.reconnectScheduler.next();\n\n\t\tthis.ctx.log('info', `Attempting reconnect to websocket sync`);\n\t};\n\n\tprivate onClose = (event: CloseEvent) => {\n\t\tthis.ctx.log('info', 'Sync socket disconnected', event.code);\n\t\tthis.onOnlineChange(false);\n\t\tif (this.disposed) return;\n\t\tthis.reconnectScheduler.next();\n\t\tthis.ctx.log('info', `Attempting reconnect to websocket sync`);\n\t};\n\n\tprivate initializeSocket = async () => {\n\t\tconst endpoint = await this.endpointProvider.getEndpoints();\n\t\t// abusing protocols to pass the auth token\n\t\tthis.socket = new this.ctx.environment.WebSocket(endpoint.websocket, [\n\t\t\t'Bearer',\n\t\t\tendpoint.token,\n\t\t]);\n\t\tthis.socket.addEventListener('message', this.onMessage);\n\t\tthis.socket.addEventListener('open', this.onOpen);\n\t\tthis.socket.addEventListener('error', this.onError);\n\t\tthis.socket.addEventListener('close', this.onClose);\n\t\treturn this.socket;\n\t};\n\n\tprivate sendHeartbeat = async () => {\n\t\tthis.send(await (await this.ctx.meta).messageCreator.createHeartbeat());\n\t};\n\n\treconnect = () => {\n\t\tthis.stop();\n\t\tthis.start();\n\t};\n\n\tprivate canSkipSyncWait = (message: ClientMessage) => {\n\t\treturn (\n\t\t\tmessage.type === 'sync' ||\n\t\t\tmessage.type === 'presence-update' ||\n\t\t\tmessage.type === 'sync-ack' ||\n\t\t\tmessage.type === 'heartbeat'\n\t\t);\n\t};\n\n\tsend = (message: ClientMessage) => {\n\t\tif (this.status !== 'active') {\n\t\t\tthis.ctx.log(\n\t\t\t\t'debug',\n\t\t\t\t'Ignoring outgoing message',\n\t\t\t\tmessage.type,\n\t\t\t\t'sync is not active',\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// wait until a sync has started before doing anything other than sync.\n\t\t// new \"op\" messages can arrive before sync has started, so we need to wait\n\t\tif (!this.hasStartedSync && !this.canSkipSyncWait(message)) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'debug',\n\t\t\t\t'Ignoring outgoing message',\n\t\t\t\tmessage.type,\n\t\t\t\t'still waiting to begin initial sync',\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.canSkipSyncWait(message)) {\n\t\t\tif (this.socket?.readyState === WEBSOCKET_OPEN) {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'Sending message',\n\t\t\t\t\tJSON.stringify(message, null, 2),\n\t\t\t\t);\n\t\t\t\tthis.socket!.send(JSON.stringify(message));\n\t\t\t} else {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'Enqueueing message until socket is open',\n\t\t\t\t\tJSON.stringify(message, null, 2),\n\t\t\t\t);\n\t\t\t\tthis.connectQueue.push(message);\n\t\t\t}\n\t\t} else if (this.synced) {\n\t\t\tif (this.socket?.readyState === WEBSOCKET_OPEN) {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'Sending message',\n\t\t\t\t\tJSON.stringify(message, null, 2),\n\t\t\t\t);\n\t\t\t\tthis.socket.send(JSON.stringify(message));\n\t\t\t}\n\t\t} else if (this.hasStartedSync) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'debug',\n\t\t\t\t'Enqueueing message until synced',\n\t\t\t\tJSON.stringify(message, null, 2),\n\t\t\t);\n\t\t\tthis.syncQueue.push(message);\n\t\t}\n\t};\n\n\tsendDisconnecting = async (reason = 'client-shutdown') => {\n\t\treturn this.send(\n\t\t\tawait (await this.ctx.meta).messageCreator.createDisconnecting(reason),\n\t\t);\n\t};\n\n\tdestroy = () => {\n\t\tthis.dispose();\n\t\tthis.stop();\n\t};\n\n\tstart = async () => {\n\t\tif (this.socket) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.initializeSocket();\n\t\tthis._status = 'active';\n\t};\n\n\tstop = async () => {\n\t\tawait this.sendDisconnecting();\n\t\tthis.socket?.removeEventListener('message', this.onMessage);\n\t\tthis.socket?.removeEventListener('close', this.onClose);\n\t\tif (this.socket?.readyState === WEBSOCKET_OPEN) {\n\t\t\tthis.socket.close();\n\t\t}\n\t\tthis.socket = null;\n\t\tthis._status = 'paused';\n\t};\n\n\tignoreIncoming(): void {\n\t\tthis.incomingQueue = [];\n\t\tthis._ignoreIncoming = true;\n\t}\n\n\tget isConnected() {\n\t\treturn this.socket?.readyState === WEBSOCKET_OPEN;\n\t}\n\n\tget status() {\n\t\treturn this._status;\n\t}\n}\n\nconst WEBSOCKET_OPEN = 1;\n", "import {\n\tClientMessage,\n\tDocumentBaseline,\n\tEventSubscriber,\n\tFileData,\n\tOperation,\n\tReplicaType,\n\trewriteAuthzOriginator,\n\tServerMessage,\n\tVerdantError,\n\tVerdantInternalPresence,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { attemptToRegisterBackgroundSync } from './background.js';\nimport { FilePullResult, FileSync, FileUploadResult } from './FileSync.js';\nimport { HANDLE_MESSAGE, PresenceManager } from './PresenceManager.js';\nimport { PushPullSync } from './PushPullSync.js';\nimport {\n\tServerSyncEndpointProvider,\n\tServerSyncEndpointProviderConfig,\n} from './ServerSyncEndpointProvider.js';\nimport { WebSocketSync } from './WebSocketSync.js';\n\ntype SyncEvents = {\n\tonlineChange: (isOnline: boolean) => void;\n\tsyncingChange: (syncing: boolean) => void;\n\tsynced: () => void;\n\t/** When the server has lost data and re-requests data from the past */\n\tserverReset: (since: string | null) => void;\n};\n\nexport type SyncTransportEvents = SyncEvents & {\n\tmessage: (message: ServerMessage) => void;\n};\n\nexport interface SyncTransport extends EventSubscriber<SyncTransportEvents> {\n\treadonly presence: PresenceManager;\n\n\treadonly mode: SyncTransportMode;\n\treadonly hasSynced: boolean;\n\n\tsend(message: ClientMessage): void;\n\n\tstart(): Promise<void>;\n\tignoreIncoming(): void;\n\tstop(): Promise<void> | void;\n\n\tdestroy(): void;\n\n\treconnect(): void;\n\n\treadonly isConnected: boolean;\n\treadonly status: 'active' | 'paused';\n}\n\nexport interface Sync<Presence = any, Profile = any>\n\textends EventSubscriber<SyncEvents> {\n\tsetMode(mode: SyncTransportMode): void;\n\tsetPullInterval(interval: number): void;\n\treadonly pullInterval: number;\n\tuploadFile(data: FileData): Promise<FileUploadResult>;\n\tgetFile(fileId: string): Promise<FilePullResult>;\n\treadonly presence: PresenceManager<Profile, Presence>;\n\tsend(message: ClientMessage): void;\n\tstart(): Promise<void>;\n\tstop(): Promise<void> | void;\n\tignoreIncoming(): void;\n\tdestroy(): void;\n\treconnect(): void;\n\tsyncOnce(): Promise<void>;\n\treadonly isConnected: boolean;\n\treadonly status: 'active' | 'paused';\n\treadonly mode: SyncTransportMode;\n\treadonly hasSynced: boolean;\n}\n\nexport class NoSync<Presence = any, Profile = any>\n\textends EventSubscriber<SyncEvents>\n\timplements Sync<Presence, Profile>\n{\n\treadonly mode = 'pull';\n\treadonly hasSynced = false;\n\n\tpublic send(): void {}\n\n\tpublic async start(): Promise<void> {}\n\n\tpublic stop(): void {}\n\n\tpublic ignoreIncoming(): void {}\n\n\tpublic destroy = () => {};\n\n\tpublic reconnect(): void {}\n\n\tpublic setMode(): void {}\n\tpublic setPullInterval(): void {}\n\n\tpublic readonly isConnected = false;\n\tpublic readonly status = 'paused';\n\tpublic readonly pullInterval = 0;\n\n\tpublic readonly presence;\n\n\tconstructor(ctx: Context) {\n\t\tsuper();\n\t\tthis.presence = new PresenceManager({\n\t\t\tinitialPresence: null as any,\n\t\t\tdefaultProfile: null as any,\n\t\t\tctx,\n\t\t});\n\t}\n\n\tuploadFile = async () => {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tretry: false,\n\t\t};\n\t};\n\n\tgetFile = async (): Promise<FilePullResult> => {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: 'Sync is not active',\n\t\t};\n\t};\n\n\tsyncOnce: () => Promise<void> = async () => {};\n}\n\nexport type SyncTransportMode = 'realtime' | 'pull';\n\nexport interface ServerSyncOptions<Profile = any, Presence = any>\n\textends ServerSyncEndpointProviderConfig {\n\t/**\n\t * When a client first connects, it will use this presence value.\n\t */\n\tinitialPresence: Presence;\n\t/**\n\t * Before connecting to the server, the local client will have\n\t * this value for their profile data. You can either cache and store\n\t * profile data from a previous connection or provide defaults like\n\t * empty strings.\n\t */\n\tdefaultProfile: Profile;\n\n\t/**\n\t * Provide `false` to disable transport selection. Transport selection\n\t * automatically switches between HTTP and WebSocket based sync depending\n\t * on the number of peers connected. If a user is alone, they will use\n\t * HTTP push/pull to sync changes. If another user joins, both users will\n\t * be upgraded to websockets.\n\t *\n\t * Provide `peers-only` to only automatically use websockets if other\n\t * users connect, but not if another device for the current user connects.\n\t * By default, automatic transport selection will upgrade to websockets if\n\t * another device from the current user connects, but if realtime sync is\n\t * not necessary for such cases, you can save bandwidth by disabling this.\n\t *\n\t * Turning off this feature allows you more control over the transport\n\t * which can be useful for low-power devices or to save server traffic.\n\t * To modify transport modes manually, utilize `client.sync.setMode`.\n\t * The built-in behavior is essentially switching modes based on\n\t * the number of peers detected by client.sync.presence.\n\t */\n\tautomaticTransportSelection?: boolean | 'peers-only';\n\tinitialTransport?: SyncTransportMode;\n\tautoStart?: boolean;\n\t/**\n\t * Optionally specify an interval, in milliseconds, to poll the server\n\t * when in pull mode.\n\t */\n\tpullInterval?: number;\n\t/**\n\t * Presence updates are batched to reduce number of requests / messages\n\t * sent to the server. You can specify the batching time slice, in milliseconds,\n\t */\n\tpresenceUpdateBatchTimeout?: number;\n\t/**\n\t * Experimental: sync messages over a broadcast channel between tabs.\n\t * Fixes tabs not reactively updating to changes when other tabs are open,\n\t * but is not yet thoroughly vetted.\n\t */\n\tuseBroadcastChannel?: boolean;\n\t/**\n\t * Listen for outgoing messages from the client to the server.\n\t * Not sure why you want to do this, but be careful.\n\t */\n\tonOutgoingMessage?: (message: ClientMessage) => void;\n\n\tEXPERIMENTAL_backgroundSync?: boolean;\n}\n\nexport class ServerSync<Presence = any, Profile = any>\n\textends EventSubscriber<SyncEvents>\n\timplements Sync<Presence, Profile>\n{\n\tprivate webSocketSync: WebSocketSync;\n\tprivate pushPullSync: PushPullSync;\n\tprivate fileSync: FileSync;\n\tprivate activeSync: SyncTransport;\n\tprivate endpointProvider;\n\tprivate onData: (data: {\n\t\toperations: Operation[];\n\t\tbaselines?: DocumentBaseline[];\n\t\treset?: boolean;\n\t}) => Promise<void>;\n\tprivate broadcastChannel: BroadcastChannel | null = null;\n\tprivate _activelySyncing = false;\n\tprivate _hasSynced = false;\n\n\treadonly presence: PresenceManager<Profile, Presence>;\n\n\tprivate onOutgoingMessage?: (message: ClientMessage) => void;\n\n\tprivate ctx;\n\n\tconstructor(\n\t\t{\n\t\t\tauthEndpoint,\n\t\t\tfetchAuth,\n\t\t\tinitialPresence,\n\t\t\tautomaticTransportSelection = true,\n\t\t\tautoStart,\n\t\t\tinitialTransport,\n\t\t\tpullInterval,\n\t\t\tpresenceUpdateBatchTimeout,\n\t\t\tdefaultProfile,\n\t\t\tuseBroadcastChannel,\n\t\t\tonOutgoingMessage,\n\t\t\tEXPERIMENTAL_backgroundSync,\n\t\t}: ServerSyncOptions<Profile, Presence>,\n\t\t{\n\t\t\tctx,\n\t\t\tonData,\n\t\t}: {\n\t\t\tctx: Context;\n\t\t\tonData: (data: {\n\t\t\t\toperations: Operation[];\n\t\t\t\tbaselines?: DocumentBaseline[];\n\t\t\t\treset?: boolean;\n\t\t\t}) => Promise<void>;\n\t\t},\n\t) {\n\t\tsuper();\n\t\tthis.onData = onData;\n\t\tthis.ctx = ctx;\n\t\tthis.onOutgoingMessage = onOutgoingMessage;\n\t\tthis.presence = new PresenceManager({\n\t\t\tinitialPresence,\n\t\t\tdefaultProfile,\n\t\t\tupdateBatchTimeout: presenceUpdateBatchTimeout,\n\t\t\tctx,\n\t\t});\n\t\tthis.endpointProvider = new ServerSyncEndpointProvider(\n\t\t\t{\n\t\t\t\tauthEndpoint,\n\t\t\t\tfetchAuth,\n\t\t\t},\n\t\t\tctx,\n\t\t);\n\n\t\tthis.webSocketSync = new WebSocketSync({\n\t\t\tendpointProvider: this.endpointProvider,\n\t\t\tpresence: this.presence,\n\t\t\tctx,\n\t\t});\n\t\tthis.pushPullSync = new PushPullSync({\n\t\t\tendpointProvider: this.endpointProvider,\n\t\t\tpresence: this.presence,\n\t\t\tinterval: pullInterval,\n\t\t\tctx,\n\t\t});\n\t\tthis.fileSync = new FileSync({\n\t\t\tendpointProvider: this.endpointProvider,\n\t\t\tctx,\n\t\t});\n\t\tif (useBroadcastChannel && 'BroadcastChannel' in window) {\n\t\t\tthis.broadcastChannel = new BroadcastChannel(`verdant-${ctx.namespace}`);\n\t\t\tthis.broadcastChannel.addEventListener(\n\t\t\t\t'message',\n\t\t\t\tthis.handleBroadcastChannelMessage,\n\t\t\t);\n\t\t}\n\t\tctx.log(\n\t\t\t'info',\n\t\t\t'Sync initialized with transport:',\n\t\t\tinitialTransport ?? 'pull',\n\t\t);\n\t\tif (initialTransport === 'realtime') {\n\t\t\tthis.activeSync = this.webSocketSync;\n\t\t} else {\n\t\t\tthis.activeSync = this.pushPullSync;\n\t\t}\n\n\t\tthis.presence.subscribe('update', this.handlePresenceUpdate);\n\n\t\tctx.internalEvents.subscribe('outgoingSyncMessage', this.send);\n\t\tthis.webSocketSync.subscribe('message', this.handleMessage);\n\t\tthis.webSocketSync.subscribe('onlineChange', this.handleOnlineChange);\n\n\t\tthis.pushPullSync.subscribe('message', this.handleMessage);\n\t\tthis.pushPullSync.subscribe('onlineChange', this.handleOnlineChange);\n\n\t\tif (automaticTransportSelection && this.canDoRealtime) {\n\t\t\t// automatically shift between transport modes depending\n\t\t\t// on whether any peers are present (matching view if\n\t\t\t// applicable)\n\t\t\tconst decideIfUpgrade = () => {\n\t\t\t\tif (switchoverTimeout) {\n\t\t\t\t\tclearTimeout(switchoverTimeout);\n\t\t\t\t}\n\t\t\t\tconst hasPeers = this.presence.getViewPeers().length > 0;\n\t\t\t\tconst shouldUpgrade =\n\t\t\t\t\thasPeers ||\n\t\t\t\t\t(automaticTransportSelection !== 'peers-only' &&\n\t\t\t\t\t\tthis.presence.selfReplicaIds.size > 1);\n\t\t\t\tif (shouldUpgrade && this.mode === 'pull') {\n\t\t\t\t\tthis.setMode('realtime');\n\t\t\t\t} else if (!shouldUpgrade && this.mode === 'realtime') {\n\t\t\t\t\t// wait 1 second then switch to pull mode if still empty\n\t\t\t\t\tswitchoverTimeout = setTimeout(() => {\n\t\t\t\t\t\tif (this.presence.getViewPeers().length === 0) {\n\t\t\t\t\t\t\tthis.setMode('pull');\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 1000);\n\t\t\t\t}\n\t\t\t};\n\t\t\tlet switchoverTimeout: NodeJS.Timeout;\n\t\t\tthis.presence.subscribe('peersChanged', decideIfUpgrade);\n\t\t\tif (automaticTransportSelection !== 'peers-only') {\n\t\t\t\tthis.presence.subscribe('selfChanged', decideIfUpgrade);\n\t\t\t}\n\t\t}\n\n\t\tif (autoStart) {\n\t\t\tthis.start();\n\t\t}\n\n\t\tif (EXPERIMENTAL_backgroundSync) {\n\t\t\tattemptToRegisterBackgroundSync();\n\t\t}\n\t}\n\n\tget canDoRealtime() {\n\t\treturn (\n\t\t\tthis.endpointProvider.type === ReplicaType.Realtime ||\n\t\t\tthis.endpointProvider.type === ReplicaType.PassiveRealtime ||\n\t\t\tthis.endpointProvider.type === ReplicaType.ReadOnlyRealtime\n\t\t);\n\t}\n\n\tget syncing() {\n\t\treturn this._activelySyncing;\n\t}\n\n\tget hasSynced() {\n\t\treturn this._hasSynced;\n\t}\n\n\tprivate handleBroadcastChannelMessage = (event: MessageEvent) => {\n\t\tif (event.data.type === 'sync') {\n\t\t\tthis.handleMessage(event.data.message, { source: 'broadcastChannel' });\n\t\t}\n\t};\n\n\tprivate handleMessage = async (\n\t\tmessage: ServerMessage,\n\t\t{ source }: { source: 'network' | 'broadcastChannel' } = {\n\t\t\tsource: 'network',\n\t\t},\n\t) => {\n\t\t// cancel if client is shutting down\n\t\tif (this.ctx.closing) return;\n\n\t\t// TODO: move this into metadata\n\t\tif (message.type === 'op-re' || message.type === 'sync-resp') {\n\t\t\tfor (const op of message.operations) {\n\t\t\t\tthis.ctx.time.update(op.timestamp);\n\t\t\t}\n\t\t}\n\n\t\tthis.ctx.log('debug', 'sync message', JSON.stringify(message, null, 2));\n\t\tswitch (message.type) {\n\t\t\tcase 'op-re':\n\t\t\t\tawait this.onData({\n\t\t\t\t\toperations: message.operations,\n\t\t\t\t\tbaselines: message.baselines,\n\t\t\t\t});\n\t\t\t\tif (message.globalAckTimestamp) {\n\t\t\t\t\tawait (await this.ctx.meta).setGlobalAck(message.globalAckTimestamp);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'global-ack':\n\t\t\t\tawait (await this.ctx.meta).setGlobalAck(message.timestamp);\n\t\t\t\tbreak;\n\t\t\tcase 'sync-resp':\n\t\t\t\tthis._activelySyncing = true;\n\t\t\t\tthis.emit('syncingChange', true);\n\t\t\t\tawait this.onData({\n\t\t\t\t\toperations: message.operations,\n\t\t\t\t\tbaselines: message.baselines,\n\t\t\t\t\treset: message.overwriteLocalData,\n\t\t\t\t});\n\n\t\t\t\tif (message.globalAckTimestamp) {\n\t\t\t\t\tawait (await this.ctx.meta).setGlobalAck(message.globalAckTimestamp);\n\t\t\t\t}\n\n\t\t\t\tawait (await this.ctx.meta).updateLastSynced(message.ackedTimestamp);\n\t\t\t\tthis._activelySyncing = false;\n\t\t\t\tthis.emit('syncingChange', false);\n\t\t\t\tthis._hasSynced = true;\n\t\t\t\tthis.emit('synced');\n\t\t\t\tbreak;\n\t\t\tcase 'need-since':\n\t\t\t\tthis.emit('serverReset', message.since);\n\t\t\t\t(await this.ctx.files).onServerReset(message.since);\n\t\t\t\tthis.activeSync.send(\n\t\t\t\t\tawait (\n\t\t\t\t\t\tawait this.ctx.meta\n\t\t\t\t\t).messageCreator.createSyncStep1(message.since),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase 'server-ack':\n\t\t\t\tawait (await this.ctx.meta).updateLastSynced(message.timestamp);\n\t\t}\n\n\t\t// avoid rebroadcasting messages\n\t\tif (source === 'network') {\n\t\t\tthis.broadcastChannel?.postMessage({\n\t\t\t\ttype: 'sync',\n\t\t\t\tmessage,\n\t\t\t});\n\t\t}\n\n\t\t// update presence if necessary\n\t\tthis.presence[HANDLE_MESSAGE](\n\t\t\tawait (await this.ctx.meta).getLocalReplica(),\n\t\t\tmessage,\n\t\t);\n\t};\n\tprivate handleOnlineChange = async (online: boolean) => {\n\t\tthis.emit('onlineChange', online);\n\n\t\t// if online, attempt to upload any unsynced files.\n\t\tif (online) {\n\t\t\tconst unsyncedFiles = await (await this.ctx.files).listUnsynced();\n\t\t\tconst results = await Promise.allSettled(\n\t\t\t\tunsyncedFiles.map((file) => this.fileSync.uploadFile(file)),\n\t\t\t);\n\t\t\tif (results.some((r) => r.status === 'rejected')) {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'error',\n\t\t\t\t\t'Failed to upload unsynced files',\n\t\t\t\t\tresults\n\t\t\t\t\t\t.filter((r): r is PromiseRejectedResult => r.status === 'rejected')\n\t\t\t\t\t\t.map((r) => r.reason),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t};\n\tprivate handlePresenceUpdate = async (data: {\n\t\tpresence?: Presence;\n\t\tinternal?: VerdantInternalPresence;\n\t}) => {\n\t\tthis.send(\n\t\t\tawait (await this.ctx.meta).messageCreator.createPresenceUpdate(data),\n\t\t);\n\t};\n\n\tsetMode = (transport: SyncTransportMode) => {\n\t\tif (transport === 'realtime' && !this.canDoRealtime) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot switch to realtime mode, because the current auth token does not allow it`,\n\t\t\t);\n\t\t}\n\n\t\tlet newSync: SyncTransport;\n\t\tif (transport === 'realtime') {\n\t\t\tnewSync = this.webSocketSync;\n\t\t} else {\n\t\t\tnewSync = this.pushPullSync;\n\t\t}\n\n\t\tif (newSync === this.activeSync) return;\n\t\tthis.ctx.log('debug', 'switching to', transport, 'mode');\n\n\t\t// transfer state to new sync\n\t\tif (this.activeSync.status === 'active') {\n\t\t\tnewSync.start();\n\t\t}\n\t\tthis.activeSync.stop();\n\t\tthis.activeSync = newSync;\n\t};\n\n\tsetPullInterval = (interval: number) => {\n\t\tthis.pushPullSync.setInterval(interval);\n\t};\n\n\tget pullInterval() {\n\t\treturn this.pushPullSync.interval;\n\t}\n\n\tsend = async (message: ClientMessage) => {\n\t\tif (this.activeSync.status === 'active') {\n\t\t\t// before sync, replace 'originator' authz subjects\n\t\t\t// with token userId. This is the easiest place to\n\t\t\t// do this and allows the rest of the system to be\n\t\t\t// ambivalent about user identity when assigning\n\t\t\t// authorization for the current user.\n\t\t\tconst userId = this.endpointProvider.tokenInfo?.userId;\n\t\t\tif (!userId) {\n\t\t\t\tthrow new VerdantError(\n\t\t\t\t\tVerdantError.Code.Unexpected,\n\t\t\t\t\tundefined,\n\t\t\t\t\t'Active sync has invalid token info',\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (message.type === 'sync' || message.type === 'op') {\n\t\t\t\trewriteAuthzOriginator(message, userId);\n\t\t\t}\n\t\t\tthis.activeSync.send(message);\n\t\t\tthis.onOutgoingMessage?.(message);\n\t\t}\n\t};\n\n\tuploadFile = async (info: FileData) => {\n\t\tthis.ctx.log('info', 'Uploading file', {\n\t\t\tname: info.name,\n\t\t\ttype: info.type,\n\t\t\tid: info.id,\n\t\t\tsize: info.file?.size,\n\t\t});\n\t\tif (this.activeSync.status === 'active') {\n\t\t\treturn this.fileSync.uploadFile(info);\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tretry: false,\n\t\t\t\terror: 'Sync is not active',\n\t\t\t};\n\t\t}\n\t};\n\n\tgetFile = async (id: string) => {\n\t\t// TODO: should this error? or just try anyway?\n\t\tif (this.activeSync.status === 'active') {\n\t\t\treturn this.fileSync.getFile(id);\n\t\t} else {\n\t\t\t// wait for sync to start, up to 5 seconds\n\t\t\tawait this.getSyncStartPromise();\n\t\t\tif (this.activeSync.status === 'paused') {\n\t\t\t\tthrow new VerdantError(\n\t\t\t\t\tVerdantError.Code.Offline,\n\t\t\t\t\tundefined,\n\t\t\t\t\t'Sync is not active',\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn this.fileSync.getFile(id);\n\t\t}\n\t};\n\n\tprivate getSyncStartPromise = (timeout = 5000) => {\n\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\tconst timeoutHandle = setTimeout(() => {\n\t\t\t\treject(new Error('Sync did not start in time'));\n\t\t\t\tunsubscribe();\n\t\t\t}, timeout);\n\t\t\tconst unsubscribe = this.subscribe('onlineChange', (online: boolean) => {\n\t\t\t\tif (online) {\n\t\t\t\t\tclearTimeout(timeoutHandle);\n\t\t\t\t\tunsubscribe();\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t};\n\n\tpublic start = () => {\n\t\tthis.ctx.log('info', 'Starting sync');\n\t\treturn this.activeSync.start();\n\t};\n\n\tpublic stop = () => {\n\t\tthis.ctx.log('info', 'Stopping sync');\n\t\treturn this.activeSync.stop();\n\t};\n\n\tpublic ignoreIncoming(): void {\n\t\tthis.activeSync.ignoreIncoming();\n\t}\n\n\tpublic destroy = () => {\n\t\tthis.dispose();\n\t\tthis.webSocketSync.destroy();\n\t\tthis.pushPullSync.destroy();\n\t};\n\n\tpublic reconnect = () => {\n\t\treturn this.activeSync.reconnect();\n\t};\n\n\t/**\n\t * Runs one isolated sync cycle over HTTP. This is useful for\n\t * syncing via a periodic background job in a service worker,\n\t * which keeps a client up to date while the app isn't open.\n\t */\n\tpublic syncOnce = () => {\n\t\treturn this.pushPullSync.syncOnce();\n\t};\n\n\tpublic get isConnected(): boolean {\n\t\treturn this.activeSync.isConnected;\n\t}\n\n\tpublic get status() {\n\t\treturn this.activeSync.status;\n\t}\n\n\tpublic get mode() {\n\t\treturn this.activeSync.mode;\n\t}\n}\n", "import {\n\tDocumentBaseline,\n\tgetTimestampSchemaVersion,\n\tOperation,\n} from '@verdant-web/common';\n\nexport function getLatestVersion(data: {\n\toperations: Operation[];\n\tbaselines?: DocumentBaseline[];\n}) {\n\tconst timestamps = data.operations\n\t\t.map((op) => op.timestamp)\n\t\t.concat(data.baselines?.map((b) => b.timestamp) ?? []);\n\tconst latestVersion = timestamps.reduce((v, ts) => {\n\t\tconst tsVersion = getTimestampSchemaVersion(ts);\n\t\tif (tsVersion > v) {\n\t\t\treturn tsVersion;\n\t\t}\n\t\treturn v;\n\t}, 1);\n\n\treturn latestVersion;\n}\n", "import {\n\tdebounce,\n\tDocumentBaseline,\n\tEventSubscriber,\n\tFileData,\n\tOperation,\n\tVerdantError,\n} from '@verdant-web/common';\nimport { Context, ContextInit } from '../context/context.js';\nimport { DocumentManager } from '../entities/DocumentManager.js';\nimport { EntityStore } from '../entities/EntityStore.js';\nimport { FileManager } from '../files/FileManager.js';\nimport { deleteAllDatabases } from '../persistence/idb/util.js';\nimport { ExportedData } from '../persistence/interfaces.js';\nimport { importPersistence } from '../persistence/persistence.js';\nimport { CollectionQueries } from '../queries/CollectionQueries.js';\nimport { PublicQueryCacheAPI, QueryCache } from '../queries/QueryCache.js';\nimport { NoSync, ServerSync, Sync } from '../sync/Sync.js';\nimport { getLatestVersion } from '../utils/versions.js';\n\n// not actually used below, but helpful for internal code which\n// might rely on this stuff...\nexport type ClientWithCollections = Client & {\n\t[key: string]: CollectionQueries<any, any, any>;\n};\n\nexport class Client<Presence = any, Profile = any> extends EventSubscriber<{\n\t/**\n\t * Called when a change from a future version of the application has\n\t * been witnessed. These changes are not applied but it indicates\n\t * the app has been updated and a peer is using a newer version.\n\t * You should listen to this event and prompt the user to reload\n\t * their client, or reload it for them.\n\t *\n\t * This event may be called multiple times.\n\t */\n\tfutureSeen: () => void;\n\t/**\n\t * The server requested this replica reset its state\n\t * completely. This can happen when the replica has\n\t * been offline for too long and reconnects.\n\t */\n\tresetToServer: () => void;\n\t/**\n\t * These are errors that, as a developer, you should subscribe to\n\t * and prompt users to contact you for resolution. Usually these errors\n\t * indicate the client is in an unrecoverable state.\n\t */\n\tdeveloperError: (err: Error) => void;\n\t/**\n\t * Listen for operations as they are applied to the database.\n\t * Wouldn't recommend using this unless you know what you're doing.\n\t * It's a very hot code path...\n\t */\n\toperation: (operation: Operation) => void;\n\t/**\n\t * Emitted when storage rebases history. This should never actually affect application behavior\n\t * or stored data, but is useful for debugging and testing.\n\t */\n\trebase: () => void;\n\t/**\n\t * Emitted when a file is stored locally. Used for test coordination right now.\n\t */\n\tfileSaved: (fileData: FileData) => void;\n}> {\n\tprivate _entities: EntityStore;\n\tprivate _queryCache: QueryCache;\n\tprivate _documentManager: DocumentManager<any>;\n\tprivate _fileManager: FileManager;\n\tprivate context: Context;\n\n\treadonly collectionNames: string[];\n\n\tprivate _sync!: Sync<Presence, Profile>;\n\n\tconstructor(private contextInit: ContextInit) {\n\t\tsuper();\n\t\tthis.context = new Context(this.contextInit);\n\t\tthis.context.getClient = () => this;\n\n\t\tthis.collectionNames = Object.keys(this.context.schema.collections);\n\t\tthis._sync =\n\t\t\tthis.context.config.sync && !this.context.schema.wip\n\t\t\t\t? new ServerSync<Presence, Profile>(this.context.config.sync, {\n\t\t\t\t\t\tonData: this.addData,\n\t\t\t\t\t\tctx: this.context,\n\t\t\t\t\t})\n\t\t\t\t: new NoSync<Presence, Profile>(this.context);\n\t\tif (this.context.schema.wip && this.context.config.sync) {\n\t\t\tthis.context.log(\n\t\t\t\t'warn',\n\t\t\t\t'\u26A0\uFE0F\u26A0\uFE0F Sync is disabled for WIP schemas. Commit your schema changes to start syncing again. \u26A0\uFE0F\u26A0\uFE0F',\n\t\t\t);\n\t\t}\n\n\t\tthis._fileManager = new FileManager({\n\t\t\tsync: this.sync,\n\t\t\tcontext: this.context,\n\t\t});\n\t\tthis._entities = new EntityStore({\n\t\t\tctx: this.context,\n\t\t\tfiles: this._fileManager,\n\t\t});\n\t\t// note: query cache must be initialized after EntityStore,\n\t\t// since EntityStore needs to clear its cache before queries\n\t\t// refresh.\n\t\t// FIXME: make this less fragile\n\t\tthis._queryCache = new QueryCache({\n\t\t\tcontext: this.context,\n\t\t\tevictionTime: this.context.config.queries?.evictionTime,\n\t\t});\n\t\tthis._documentManager = new DocumentManager(this.schema, this._entities);\n\n\t\tconst notifyFutureSeen = debounce(() => {\n\t\t\tthis.emit('futureSeen');\n\t\t}, 300);\n\t\tthis.context.globalEvents.subscribe('futureSeen', notifyFutureSeen);\n\t\tthis.context.globalEvents.subscribe('resetToServer', () => {\n\t\t\tthis.emit('resetToServer');\n\t\t});\n\t\tthis.context.globalEvents.subscribe('operation', (operation) => {\n\t\t\tthis.emit('operation', operation);\n\t\t});\n\t\tthis.context.globalEvents.subscribe('rebase', () => {\n\t\t\tthis.emit('rebase');\n\t\t});\n\t\tthis.context.globalEvents.subscribe('fileSaved', (file) => {\n\t\t\tthis.emit('fileSaved', file);\n\t\t});\n\n\t\t// self-assign collection shortcuts. these are not typed\n\t\t// here but are typed in the generated code...\n\t\tfor (const [name, _collection] of Object.entries(\n\t\t\tthis.context.schema.collections,\n\t\t)) {\n\t\t\tconst collectionName = name;\n\t\t\t(this as any)[collectionName] = new CollectionQueries({\n\t\t\t\tcollection: collectionName,\n\t\t\t\tcache: this._queryCache,\n\t\t\t\tcontext: this.context,\n\t\t\t\tentities: this.entities,\n\t\t\t\tdocumentManager: this.documentManager,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate importingPromise = Promise.resolve();\n\tprivate addData = async (data: {\n\t\toperations: Operation[];\n\t\tbaselines?: DocumentBaseline[];\n\t\treset?: boolean;\n\t}) => {\n\t\tif (this.context.closing) {\n\t\t\tthis.context.log(\n\t\t\t\t'warn',\n\t\t\t\t'Client is closing; ignoring incoming sync data',\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\t// always wait for an ongoing import to complete before handling data.\n\t\tawait this.importingPromise;\n\n\t\ttry {\n\t\t\tconst schemaVersion = data.reset\n\t\t\t\t? getLatestVersion(data)\n\t\t\t\t: this.schema.version;\n\n\t\t\tif (schemaVersion < this.schema.version) {\n\t\t\t\t/**\n\t\t\t\t * Edge case: the server has an older version of the library\n\t\t\t\t * than the client schema, but it wants the client to reset.\n\t\t\t\t *\n\t\t\t\t * This happens when a truant or new client loads up newest client\n\t\t\t\t * code with a new schema version, but the last sync to the\n\t\t\t\t * server was from an old version. It's particularly a problem\n\t\t\t\t * if the new schema drops collections, since the IDB table for\n\t\t\t\t * that collection will no longer exist, so loading in old data\n\t\t\t\t * will result in an error.\n\t\t\t\t *\n\t\t\t\t * To handle this, we treat the reset data as if it were an import\n\t\t\t\t * of exported data. The import procedure handles older\n\t\t\t\t * schema versions by resetting the database to the imported\n\t\t\t\t * version, then migrating up to the current version.\n\t\t\t\t */\n\t\t\t\tthis.context.log(\n\t\t\t\t\t'warn',\n\t\t\t\t\t'Incoming reset sync data is from an old schema version',\n\t\t\t\t\tschemaVersion,\n\t\t\t\t\t`(current ${this.schema.version})`,\n\t\t\t\t);\n\t\t\t\t// run through the import flow to properly handle old versions\n\t\t\t\treturn await this.import({\n\t\t\t\t\tdata: {\n\t\t\t\t\t\toperations: data.operations,\n\t\t\t\t\t\tbaselines: data.baselines ?? [],\n\t\t\t\t\t\t// keep existing\n\t\t\t\t\t\tlocalReplica: undefined,\n\t\t\t\t\t\tschemaVersion,\n\t\t\t\t\t},\n\t\t\t\t\tfileData: [],\n\t\t\t\t\tfiles: [],\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\treturn await this._entities.addData(data);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthis.context.log(\n\t\t\t\t'critical',\n\t\t\t\t'Sync failed. To avoid data corruption, the client will now shut down.',\n\t\t\t\terr,\n\t\t\t);\n\t\t\tthis.emit(\n\t\t\t\t'developerError',\n\t\t\t\tnew VerdantError(\n\t\t\t\t\tVerdantError.Code.Unexpected,\n\t\t\t\t\terr as any,\n\t\t\t\t\t'Sync failed. To avoid data corruption, the client will now shut down.',\n\t\t\t\t),\n\t\t\t);\n\t\t\tawait this.close();\n\t\t\tthrow err;\n\t\t}\n\t};\n\n\tget schema() {\n\t\treturn this.context.schema;\n\t}\n\n\tget namespace() {\n\t\treturn this.context.namespace;\n\t}\n\n\tget undoHistory() {\n\t\treturn this.context.undoHistory;\n\t}\n\n\tget queries(): PublicQueryCacheAPI {\n\t\treturn this._queryCache;\n\t}\n\n\tget sync() {\n\t\treturn this._sync;\n\t}\n\n\tget entities() {\n\t\treturn this._entities;\n\t}\n\n\tget documentManager() {\n\t\treturn this._documentManager;\n\t}\n\n\tasync getReplicaId() {\n\t\tconst replica = await (await this.context.meta).getLocalReplica();\n\t\treturn replica.id;\n\t}\n\n\t/**\n\t * Batch multiple operations together to be executed in a single transaction.\n\t * The changes made will not be included in the same undo history step as\n\t * any other changes made outside of the batch. You can also disable undo\n\t * for your batch to omit changes from undo history.\n\t *\n\t * Provide a batch name to apply multiple changes to the same batch\n\t * across different invocations. Batches will automatically flush after\n\t * a short delay or if they reach a maximum size.\n\t */\n\tget batch() {\n\t\treturn this.entities.batch;\n\t}\n\n\tstats = async (): Promise<ClientStats> => {\n\t\tif (this.disposed) {\n\t\t\treturn {} as any;\n\t\t}\n\t\tconst collections = await (await this.context.documents).stats();\n\t\tconst meta = await (await this.context.meta).stats();\n\t\tconst storage =\n\t\t\ttypeof navigator !== 'undefined' &&\n\t\t\ttypeof navigator.storage !== 'undefined' &&\n\t\t\t'estimate' in navigator.storage\n\t\t\t\t? await navigator.storage.estimate()\n\t\t\t\t: undefined;\n\n\t\tconst files = await (await this.context.files).stats();\n\n\t\t// determine data:metadata ratio for total size of all collections vs metadata\n\t\tconst totalCollectionsSize = Object.values(collections).reduce(\n\t\t\t(acc, { size }) => acc + size,\n\t\t\t0,\n\t\t);\n\t\tconst totalMetaSize = meta.baselinesSize.size + meta.operationsSize.size;\n\t\tconst metaToDataRatio = totalMetaSize / totalCollectionsSize;\n\n\t\treturn {\n\t\t\tcollections,\n\t\t\tmeta,\n\t\t\tstorage,\n\t\t\ttotalMetaSize,\n\t\t\ttotalCollectionsSize,\n\t\t\tmetaToDataRatio,\n\t\t\tfiles,\n\t\t\tquotaUsage:\n\t\t\t\tstorage?.usage && storage?.quota\n\t\t\t\t\t? storage.usage / storage.quota\n\t\t\t\t\t: undefined,\n\t\t};\n\t};\n\n\tclose = async () => {\n\t\tthis.sync.ignoreIncoming();\n\t\tawait this._entities.flushAllBatches();\n\t\t// NOTE: this happens after flushing or else flushed data\n\t\t// won't be written to storage or synced.\n\t\tthis.context.closing = true;\n\t\tif (this.context.closeLock) {\n\t\t\tawait this.context.closeLock;\n\t\t}\n\t\tawait this.sync.stop();\n\t\tthis.sync.destroy();\n\t\t// this step does have the potential to flush\n\t\t// changes to storage, so don't close metadata db yet\n\t\tawait this._entities.destroy();\n\n\t\tthis.context.persistenceShutdownHandler.shutdown();\n\t\tthis.context.internalEvents.disable();\n\t\tthis.context.entityEvents.disable();\n\n\t\t// the idea here is to flush the microtask queue -\n\t\t// we may have queued tasks related to queries that\n\t\t// we want to settle before closing the databases\n\t\t// to avoid invalid state errors\n\t\tawait new Promise<void>((resolve) => {\n\t\t\tresolve();\n\t\t});\n\n\t\tthis.context.log?.('info', 'Client closed');\n\t};\n\n\t__dangerous__resetLocal = async () => {\n\t\tthis.sync.stop();\n\t\tawait deleteAllDatabases(this.namespace, this.context.environment);\n\t};\n\n\texport = async (\n\t\t{ downloadRemoteFiles }: { downloadRemoteFiles?: boolean } = {\n\t\t\tdownloadRemoteFiles: true,\n\t\t},\n\t): Promise<ExportedData> => {\n\t\tthis.context.log('info', 'Exporting data...');\n\t\tconst metaExport = await (await this.context.meta).export();\n\t\tconst { fileData, files } = await (\n\t\t\tawait this.context.files\n\t\t).export(downloadRemoteFiles);\n\t\treturn {\n\t\t\tdata: metaExport,\n\t\t\tfileData,\n\t\t\tfiles,\n\t\t};\n\t};\n\n\timport = async ({ data, fileData, files }: ExportedData) => {\n\t\t/**\n\t\t * Importing is a pretty involved procedure because of the possibility of\n\t\t * importing an export from an older version of the schema. We can't add\n\t\t * data from older schemas because the indexes may have changed or whole\n\t\t * collections may have been since deleted, leaving no corresponding IDB\n\t\t * tables.\n\t\t *\n\t\t * Since IDB doesn't allow us to go backwards, and we are resetting all\n\t\t * data anyways, the import procedure blows away the current queryable DB\n\t\t * and restarts from the imported schema version. It then migrates up\n\t\t * to the latest (current) version. These migrations are added to the imported\n\t\t * data to produce the final state.\n\t\t */\n\n\t\t// register importing promise to halt other data handling\n\t\tlet resolve = () => {};\n\t\tthis.importingPromise = new Promise<void>((res) => {\n\t\t\tresolve = res;\n\t\t});\n\n\t\tthis.context.log('info', 'Importing data...');\n\n\t\tawait importPersistence(this.context, { data, files, fileData });\n\n\t\t// finally... clear out memory cache of entities and\n\t\t// re-run all active queries.\n\t\t// this.entities.clearCache();\n\t\t// this._queryCache.forceRefreshAll();\n\n\t\t// ^ this is now done via the persistenceReset internal event.\n\n\t\tresolve();\n\t};\n\n\t/**\n\t * Export all data, then re-import it. This might resolve\n\t * some issues with the local database, but it should\n\t * only be done as a second-to-last resort. The last resort\n\t * would be __dangerous__resetLocal, which\n\t * clears all local data.\n\t *\n\t * Unlike __dangerous__resetLocal, this method allows local-only\n\t * clients to recover data, whereas __dangerous__resetLocal only\n\t * lets networked clients recover from the server.\n\t */\n\t__dangerous__hardReset = async () => {\n\t\tconst exportData = await this.export();\n\t\tawait this.import(exportData);\n\t};\n\n\t/**\n\t * Immediately runs the file deletion process. This is useful\n\t * for testing, mostly. Or if your client is long-lived, since\n\t * normally this cleanup only runs on startup.\n\t *\n\t * Note this still follows the file deletion heuristic configured\n\t * on the client. So if you clean up files 3 days after delete,\n\t * invoking this manually will not skip that 3 day waiting period.\n\t */\n\t__cleanupFilesImmediately = async () => {\n\t\treturn (await this.context.files).cleanupDeletedFiles();\n\t};\n\n\t/**\n\t * Manually triggers storage rebasing. Follows normal\n\t * rebasing rules. Rebases already happen automatically\n\t * during normal operation, so you probably don't need this.\n\t */\n\t__manualRebase = async () => {\n\t\t// not awaiting; relying on event below as this method only schedules.\n\t\t(await this.context.meta).manualRebase();\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tconst unsub = this.subscribe('rebase', () => {\n\t\t\t\tunsub();\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t};\n\n\t/**\n\t * WARNING: the internal functions of the persistence layer\n\t * are not guaranteed and cannot be relied upon for application\n\t * behavior. They are subject to change without notice.\n\t */\n\tget __persistence() {\n\t\treturn {\n\t\t\tmeta: this.context.meta,\n\t\t\tqueries: this.context.documents,\n\t\t\tfiles: this.context.files,\n\t\t};\n\t}\n\n\tget __persistenceReady() {\n\t\treturn this.context.waitForInitialization;\n\t}\n}\n\nexport interface ClientStats {\n\tcollections: Record<string, { count: number; size: number }>;\n\tmeta: {\n\t\tbaselinesSize: { count: number; size: number };\n\t\toperationsSize: { count: number; size: number };\n\t};\n\tfiles: {\n\t\tsize: { count: number; size: number };\n\t};\n\tstorage: StorageEstimate | undefined;\n\ttotalMetaSize: number;\n\ttotalCollectionsSize: number;\n\tmetaToDataRatio: number;\n\tquotaUsage: number | undefined;\n}\n", "import { authz } from '@verdant-web/common';\n\nexport const authorization = {\n\tprivate: authz.onlyMe(),\n\tpublic: undefined,\n};\n", "export function cliSync<Presence extends any = any>(\n\tlibraryId: string,\n\t{\n\t\tport = 3242,\n\t\tinitialPresence = {} as any,\n\t}: { port?: number; initialPresence?: Presence } = {},\n) {\n\tlet userId = localStorage.getItem('verdant-userId');\n\tif (!userId) {\n\t\tuserId = `user-${Math.random().toString(36).slice(2)}`;\n\t\tlocalStorage.setItem('verdant-userId', userId);\n\t}\n\treturn {\n\t\tdefaultProfile: { id: userId },\n\t\tinitialPresence,\n\t\tauthEndpoint: `http://localhost:${port}/auth/${libraryId}?userId=${userId}`,\n\t};\n}\n", "import cuid from 'cuid';\n\nexport function id(short?: boolean) {\n\tif (short) return cuid.slug();\n\treturn cuid();\n}\n", "import * as everything from './index.js';\n\n(window as any).Verdant = everything;\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["!function(e){var t;\"object\"==typeof exports?module.exports=e():\"function\"==typeof define&&define.amd?define(e):(\"undefined\"!=typeof window?t=window:\"undefined\"!=typeof global?t=global:\"undefined\"!=typeof self&&(t=self),t.objectHash=e())}(function(){return function r(o,i,u){function s(n,e){if(!i[n]){if(!o[n]){var t=\"function\"==typeof require&&require;if(!e&&t)return t(n,!0);if(a)return a(n,!0);throw new Error(\"Cannot find module '\"+n+\"'\")}e=i[n]={exports:{}};o[n][0].call(e.exports,function(e){var t=o[n][1][e];return s(t||e)},e,e.exports,r,o,i,u)}return i[n].exports}for(var a=\"function\"==typeof require&&require,e=0;e<u.length;e++)s(u[e]);return s}({1:[function(w,b,m){!function(e,n,s,c,d,h,p,g,y){\"use strict\";var r=w(\"crypto\");function t(e,t){t=u(e,t);var n;return void 0===(n=\"passthrough\"!==t.algorithm?r.createHash(t.algorithm):new l).write&&(n.write=n.update,n.end=n.update),f(t,n).dispatch(e),n.update||n.end(\"\"),n.digest?n.digest(\"buffer\"===t.encoding?void 0:t.encoding):(e=n.read(),\"buffer\"!==t.encoding?e.toString(t.encoding):e)}(m=b.exports=t).sha1=function(e){return t(e)},m.keys=function(e){return t(e,{excludeValues:!0,algorithm:\"sha1\",encoding:\"hex\"})},m.MD5=function(e){return t(e,{algorithm:\"md5\",encoding:\"hex\"})},m.keysMD5=function(e){return t(e,{algorithm:\"md5\",encoding:\"hex\",excludeValues:!0})};var o=r.getHashes?r.getHashes().slice():[\"sha1\",\"md5\"],i=(o.push(\"passthrough\"),[\"buffer\",\"hex\",\"binary\",\"base64\"]);function u(e,t){var n={};if(n.algorithm=(t=t||{}).algorithm||\"sha1\",n.encoding=t.encoding||\"hex\",n.excludeValues=!!t.excludeValues,n.algorithm=n.algorithm.toLowerCase(),n.encoding=n.encoding.toLowerCase(),n.ignoreUnknown=!0===t.ignoreUnknown,n.respectType=!1!==t.respectType,n.respectFunctionNames=!1!==t.respectFunctionNames,n.respectFunctionProperties=!1!==t.respectFunctionProperties,n.unorderedArrays=!0===t.unorderedArrays,n.unorderedSets=!1!==t.unorderedSets,n.unorderedObjects=!1!==t.unorderedObjects,n.replacer=t.replacer||void 0,n.excludeKeys=t.excludeKeys||void 0,void 0===e)throw new Error(\"Object argument required.\");for(var r=0;r<o.length;++r)o[r].toLowerCase()===n.algorithm.toLowerCase()&&(n.algorithm=o[r]);if(-1===o.indexOf(n.algorithm))throw new Error('Algorithm \"'+n.algorithm+'\" not supported. supported values: '+o.join(\", \"));if(-1===i.indexOf(n.encoding)&&\"passthrough\"!==n.algorithm)throw new Error('Encoding \"'+n.encoding+'\" not supported. supported values: '+i.join(\", \"));return n}function a(e){if(\"function\"==typeof e)return null!=/^function\\s+\\w*\\s*\\(\\s*\\)\\s*{\\s+\\[native code\\]\\s+}$/i.exec(Function.prototype.toString.call(e))}function f(o,t,i){i=i||[];function u(e){return t.update?t.update(e,\"utf8\"):t.write(e,\"utf8\")}return{dispatch:function(e){return this[\"_\"+(null===(e=o.replacer?o.replacer(e):e)?\"null\":typeof e)](e)},_object:function(t){var n,e=Object.prototype.toString.call(t),r=/\\[object (.*)\\]/i.exec(e);r=(r=r?r[1]:\"unknown:[\"+e+\"]\").toLowerCase();if(0<=(e=i.indexOf(t)))return this.dispatch(\"[CIRCULAR:\"+e+\"]\");if(i.push(t),void 0!==s&&s.isBuffer&&s.isBuffer(t))return u(\"buffer:\"),u(t);if(\"object\"===r||\"function\"===r||\"asyncfunction\"===r)return e=Object.keys(t),o.unorderedObjects&&(e=e.sort()),!1===o.respectType||a(t)||e.splice(0,0,\"prototype\",\"__proto__\",\"constructor\"),o.excludeKeys&&(e=e.filter(function(e){return!o.excludeKeys(e)})),u(\"object:\"+e.length+\":\"),n=this,e.forEach(function(e){n.dispatch(e),u(\":\"),o.excludeValues||n.dispatch(t[e]),u(\",\")});if(!this[\"_\"+r]){if(o.ignoreUnknown)return u(\"[\"+r+\"]\");throw new Error('Unknown object type \"'+r+'\"')}this[\"_\"+r](t)},_array:function(e,t){t=void 0!==t?t:!1!==o.unorderedArrays;var n=this;if(u(\"array:\"+e.length+\":\"),!t||e.length<=1)return e.forEach(function(e){return n.dispatch(e)});var r=[],t=e.map(function(e){var t=new l,n=i.slice();return f(o,t,n).dispatch(e),r=r.concat(n.slice(i.length)),t.read().toString()});return i=i.concat(r),t.sort(),this._array(t,!1)},_date:function(e){return u(\"date:\"+e.toJSON())},_symbol:function(e){return u(\"symbol:\"+e.toString())},_error:function(e){return u(\"error:\"+e.toString())},_boolean:function(e){return u(\"bool:\"+e.toString())},_string:function(e){u(\"string:\"+e.length+\":\"),u(e.toString())},_function:function(e){u(\"fn:\"),a(e)?this.dispatch(\"[native]\"):this.dispatch(e.toString()),!1!==o.respectFunctionNames&&this.dispatch(\"function-name:\"+String(e.name)),o.respectFunctionProperties&&this._object(e)},_number:function(e){return u(\"number:\"+e.toString())},_xml:function(e){return u(\"xml:\"+e.toString())},_null:function(){return u(\"Null\")},_undefined:function(){return u(\"Undefined\")},_regexp:function(e){return u(\"regex:\"+e.toString())},_uint8array:function(e){return u(\"uint8array:\"),this.dispatch(Array.prototype.slice.call(e))},_uint8clampedarray:function(e){return u(\"uint8clampedarray:\"),this.dispatch(Array.prototype.slice.call(e))},_int8array:function(e){return u(\"int8array:\"),this.dispatch(Array.prototype.slice.call(e))},_uint16array:function(e){return u(\"uint16array:\"),this.dispatch(Array.prototype.slice.call(e))},_int16array:function(e){return u(\"int16array:\"),this.dispatch(Array.prototype.slice.call(e))},_uint32array:function(e){return u(\"uint32array:\"),this.dispatch(Array.prototype.slice.call(e))},_int32array:function(e){return u(\"int32array:\"),this.dispatch(Array.prototype.slice.call(e))},_float32array:function(e){return u(\"float32array:\"),this.dispatch(Array.prototype.slice.call(e))},_float64array:function(e){return u(\"float64array:\"),this.dispatch(Array.prototype.slice.call(e))},_arraybuffer:function(e){return u(\"arraybuffer:\"),this.dispatch(new Uint8Array(e))},_url:function(e){return u(\"url:\"+e.toString())},_map:function(e){u(\"map:\");e=Array.from(e);return this._array(e,!1!==o.unorderedSets)},_set:function(e){u(\"set:\");e=Array.from(e);return this._array(e,!1!==o.unorderedSets)},_file:function(e){return u(\"file:\"),this.dispatch([e.name,e.size,e.type,e.lastModfied])},_blob:function(){if(o.ignoreUnknown)return u(\"[blob]\");throw Error('Hashing Blob objects is currently not supported\\n(see https://github.com/puleos/object-hash/issues/26)\\nUse \"options.replacer\" or \"options.ignoreUnknown\"\\n')},_domwindow:function(){return u(\"domwindow\")},_bigint:function(e){return u(\"bigint:\"+e.toString())},_process:function(){return u(\"process\")},_timer:function(){return u(\"timer\")},_pipe:function(){return u(\"pipe\")},_tcp:function(){return u(\"tcp\")},_udp:function(){return u(\"udp\")},_tty:function(){return u(\"tty\")},_statwatcher:function(){return u(\"statwatcher\")},_securecontext:function(){return u(\"securecontext\")},_connection:function(){return u(\"connection\")},_zlib:function(){return u(\"zlib\")},_context:function(){return u(\"context\")},_nodescript:function(){return u(\"nodescript\")},_httpparser:function(){return u(\"httpparser\")},_dataview:function(){return u(\"dataview\")},_signal:function(){return u(\"signal\")},_fsevent:function(){return u(\"fsevent\")},_tlswrap:function(){return u(\"tlswrap\")}}}function l(){return{buf:\"\",write:function(e){this.buf+=e},end:function(e){this.buf+=e},read:function(){return this.buf}}}m.writeToStream=function(e,t,n){return void 0===n&&(n=t,t={}),f(t=u(e,t),n).dispatch(e)}}.call(this,w(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},w(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/fake_9a5aa49d.js\",\"/\")},{buffer:3,crypto:5,lYpoI2:11}],2:[function(e,t,f){!function(e,t,n,r,o,i,u,s,a){!function(e){\"use strict\";var a=\"undefined\"!=typeof Uint8Array?Uint8Array:Array,t=\"+\".charCodeAt(0),n=\"/\".charCodeAt(0),r=\"0\".charCodeAt(0),o=\"a\".charCodeAt(0),i=\"A\".charCodeAt(0),u=\"-\".charCodeAt(0),s=\"_\".charCodeAt(0);function f(e){e=e.charCodeAt(0);return e===t||e===u?62:e===n||e===s?63:e<r?-1:e<r+10?e-r+26+26:e<i+26?e-i:e<o+26?e-o+26:void 0}e.toByteArray=function(e){var t,n;if(0<e.length%4)throw new Error(\"Invalid string. Length must be a multiple of 4\");var r=e.length,r=\"=\"===e.charAt(r-2)?2:\"=\"===e.charAt(r-1)?1:0,o=new a(3*e.length/4-r),i=0<r?e.length-4:e.length,u=0;function s(e){o[u++]=e}for(t=0;t<i;t+=4,0)s((16711680&(n=f(e.charAt(t))<<18|f(e.charAt(t+1))<<12|f(e.charAt(t+2))<<6|f(e.charAt(t+3))))>>16),s((65280&n)>>8),s(255&n);return 2==r?s(255&(n=f(e.charAt(t))<<2|f(e.charAt(t+1))>>4)):1==r&&(s((n=f(e.charAt(t))<<10|f(e.charAt(t+1))<<4|f(e.charAt(t+2))>>2)>>8&255),s(255&n)),o},e.fromByteArray=function(e){var t,n,r,o,i=e.length%3,u=\"\";function s(e){return\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\".charAt(e)}for(t=0,r=e.length-i;t<r;t+=3)n=(e[t]<<16)+(e[t+1]<<8)+e[t+2],u+=s((o=n)>>18&63)+s(o>>12&63)+s(o>>6&63)+s(63&o);switch(i){case 1:u=(u+=s((n=e[e.length-1])>>2))+s(n<<4&63)+\"==\";break;case 2:u=(u=(u+=s((n=(e[e.length-2]<<8)+e[e.length-1])>>10))+s(n>>4&63))+s(n<<2&63)+\"=\"}return u}}(void 0===f?this.base64js={}:f)}.call(this,e(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},e(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/base64-js/lib/b64.js\",\"/node_modules/gulp-browserify/node_modules/base64-js/lib\")},{buffer:3,lYpoI2:11}],3:[function(O,e,H){!function(e,n,f,r,h,p,g,y,w){var a=O(\"base64-js\"),i=O(\"ieee754\");function f(e,t,n){if(!(this instanceof f))return new f(e,t,n);var r,o,i,u,s=typeof e;if(\"base64\"===t&&\"string\"==s)for(e=(u=e).trim?u.trim():u.replace(/^\\s+|\\s+$/g,\"\");e.length%4!=0;)e+=\"=\";if(\"number\"==s)r=j(e);else if(\"string\"==s)r=f.byteLength(e,t);else{if(\"object\"!=s)throw new Error(\"First argument needs to be a number, array or string.\");r=j(e.length)}if(f._useTypedArrays?o=f._augment(new Uint8Array(r)):((o=this).length=r,o._isBuffer=!0),f._useTypedArrays&&\"number\"==typeof e.byteLength)o._set(e);else if(C(u=e)||f.isBuffer(u)||u&&\"object\"==typeof u&&\"number\"==typeof u.length)for(i=0;i<r;i++)f.isBuffer(e)?o[i]=e.readUInt8(i):o[i]=e[i];else if(\"string\"==s)o.write(e,0,t);else if(\"number\"==s&&!f._useTypedArrays&&!n)for(i=0;i<r;i++)o[i]=0;return o}function b(e,t,n,r){return f._charsWritten=c(function(e){for(var t=[],n=0;n<e.length;n++)t.push(255&e.charCodeAt(n));return t}(t),e,n,r)}function m(e,t,n,r){return f._charsWritten=c(function(e){for(var t,n,r=[],o=0;o<e.length;o++)n=e.charCodeAt(o),t=n>>8,n=n%256,r.push(n),r.push(t);return r}(t),e,n,r)}function v(e,t,n){var r=\"\";n=Math.min(e.length,n);for(var o=t;o<n;o++)r+=String.fromCharCode(e[o]);return r}function o(e,t,n,r){r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(null!=t,\"missing offset\"),d(t+1<e.length,\"Trying to read beyond buffer length\"));var o,r=e.length;if(!(r<=t))return n?(o=e[t],t+1<r&&(o|=e[t+1]<<8)):(o=e[t]<<8,t+1<r&&(o|=e[t+1])),o}function u(e,t,n,r){r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(null!=t,\"missing offset\"),d(t+3<e.length,\"Trying to read beyond buffer length\"));var o,r=e.length;if(!(r<=t))return n?(t+2<r&&(o=e[t+2]<<16),t+1<r&&(o|=e[t+1]<<8),o|=e[t],t+3<r&&(o+=e[t+3]<<24>>>0)):(t+1<r&&(o=e[t+1]<<16),t+2<r&&(o|=e[t+2]<<8),t+3<r&&(o|=e[t+3]),o+=e[t]<<24>>>0),o}function _(e,t,n,r){if(r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(null!=t,\"missing offset\"),d(t+1<e.length,\"Trying to read beyond buffer length\")),!(e.length<=t))return r=o(e,t,n,!0),32768&r?-1*(65535-r+1):r}function E(e,t,n,r){if(r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(null!=t,\"missing offset\"),d(t+3<e.length,\"Trying to read beyond buffer length\")),!(e.length<=t))return r=u(e,t,n,!0),2147483648&r?-1*(4294967295-r+1):r}function I(e,t,n,r){return r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(t+3<e.length,\"Trying to read beyond buffer length\")),i.read(e,t,n,23,4)}function A(e,t,n,r){return r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(t+7<e.length,\"Trying to read beyond buffer length\")),i.read(e,t,n,52,8)}function s(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+1<e.length,\"trying to write beyond buffer length\"),Y(t,65535));o=e.length;if(!(o<=n))for(var i=0,u=Math.min(o-n,2);i<u;i++)e[n+i]=(t&255<<8*(r?i:1-i))>>>8*(r?i:1-i)}function l(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+3<e.length,\"trying to write beyond buffer length\"),Y(t,4294967295));o=e.length;if(!(o<=n))for(var i=0,u=Math.min(o-n,4);i<u;i++)e[n+i]=t>>>8*(r?i:3-i)&255}function B(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+1<e.length,\"Trying to write beyond buffer length\"),F(t,32767,-32768)),e.length<=n||s(e,0<=t?t:65535+t+1,n,r,o)}function L(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+3<e.length,\"Trying to write beyond buffer length\"),F(t,2147483647,-2147483648)),e.length<=n||l(e,0<=t?t:4294967295+t+1,n,r,o)}function U(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+3<e.length,\"Trying to write beyond buffer length\"),D(t,34028234663852886e22,-34028234663852886e22)),e.length<=n||i.write(e,t,n,r,23,4)}function x(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+7<e.length,\"Trying to write beyond buffer length\"),D(t,17976931348623157e292,-17976931348623157e292)),e.length<=n||i.write(e,t,n,r,52,8)}H.Buffer=f,H.SlowBuffer=f,H.INSPECT_MAX_BYTES=50,f.poolSize=8192,f._useTypedArrays=function(){try{var e=new ArrayBuffer(0),t=new Uint8Array(e);return t.foo=function(){return 42},42===t.foo()&&\"function\"==typeof t.subarray}catch(e){return!1}}(),f.isEncoding=function(e){switch(String(e).toLowerCase()){case\"hex\":case\"utf8\":case\"utf-8\":case\"ascii\":case\"binary\":case\"base64\":case\"raw\":case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":return!0;default:return!1}},f.isBuffer=function(e){return!(null==e||!e._isBuffer)},f.byteLength=function(e,t){var n;switch(e+=\"\",t||\"utf8\"){case\"hex\":n=e.length/2;break;case\"utf8\":case\"utf-8\":n=T(e).length;break;case\"ascii\":case\"binary\":case\"raw\":n=e.length;break;case\"base64\":n=M(e).length;break;case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":n=2*e.length;break;default:throw new Error(\"Unknown encoding\")}return n},f.concat=function(e,t){if(d(C(e),\"Usage: Buffer.concat(list, [totalLength])\\nlist should be an Array.\"),0===e.length)return new f(0);if(1===e.length)return e[0];if(\"number\"!=typeof t)for(o=t=0;o<e.length;o++)t+=e[o].length;for(var n=new f(t),r=0,o=0;o<e.length;o++){var i=e[o];i.copy(n,r),r+=i.length}return n},f.prototype.write=function(e,t,n,r){isFinite(t)?isFinite(n)||(r=n,n=void 0):(a=r,r=t,t=n,n=a),t=Number(t)||0;var o,i,u,s,a=this.length-t;switch((!n||a<(n=Number(n)))&&(n=a),r=String(r||\"utf8\").toLowerCase()){case\"hex\":o=function(e,t,n,r){n=Number(n)||0;var o=e.length-n;(!r||o<(r=Number(r)))&&(r=o),d((o=t.length)%2==0,\"Invalid hex string\"),o/2<r&&(r=o/2);for(var i=0;i<r;i++){var u=parseInt(t.substr(2*i,2),16);d(!isNaN(u),\"Invalid hex string\"),e[n+i]=u}return f._charsWritten=2*i,i}(this,e,t,n);break;case\"utf8\":case\"utf-8\":i=this,u=t,s=n,o=f._charsWritten=c(T(e),i,u,s);break;case\"ascii\":case\"binary\":o=b(this,e,t,n);break;case\"base64\":i=this,u=t,s=n,o=f._charsWritten=c(M(e),i,u,s);break;case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":o=m(this,e,t,n);break;default:throw new Error(\"Unknown encoding\")}return o},f.prototype.toString=function(e,t,n){var r,o,i,u,s=this;if(e=String(e||\"utf8\").toLowerCase(),t=Number(t)||0,(n=void 0!==n?Number(n):s.length)===t)return\"\";switch(e){case\"hex\":r=function(e,t,n){var r=e.length;(!t||t<0)&&(t=0);(!n||n<0||r<n)&&(n=r);for(var o=\"\",i=t;i<n;i++)o+=k(e[i]);return o}(s,t,n);break;case\"utf8\":case\"utf-8\":r=function(e,t,n){var r=\"\",o=\"\";n=Math.min(e.length,n);for(var i=t;i<n;i++)e[i]<=127?(r+=N(o)+String.fromCharCode(e[i]),o=\"\"):o+=\"%\"+e[i].toString(16);return r+N(o)}(s,t,n);break;case\"ascii\":case\"binary\":r=v(s,t,n);break;case\"base64\":o=s,u=n,r=0===(i=t)&&u===o.length?a.fromByteArray(o):a.fromByteArray(o.slice(i,u));break;case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":r=function(e,t,n){for(var r=e.slice(t,n),o=\"\",i=0;i<r.length;i+=2)o+=String.fromCharCode(r[i]+256*r[i+1]);return o}(s,t,n);break;default:throw new Error(\"Unknown encoding\")}return r},f.prototype.toJSON=function(){return{type:\"Buffer\",data:Array.prototype.slice.call(this._arr||this,0)}},f.prototype.copy=function(e,t,n,r){if(t=t||0,(r=r||0===r?r:this.length)!==(n=n||0)&&0!==e.length&&0!==this.length){d(n<=r,\"sourceEnd < sourceStart\"),d(0<=t&&t<e.length,\"targetStart out of bounds\"),d(0<=n&&n<this.length,\"sourceStart out of bounds\"),d(0<=r&&r<=this.length,\"sourceEnd out of bounds\"),r>this.length&&(r=this.length);var o=(r=e.length-t<r-n?e.length-t+n:r)-n;if(o<100||!f._useTypedArrays)for(var i=0;i<o;i++)e[i+t]=this[i+n];else e._set(this.subarray(n,n+o),t)}},f.prototype.slice=function(e,t){var n=this.length;if(e=S(e,n,0),t=S(t,n,n),f._useTypedArrays)return f._augment(this.subarray(e,t));for(var r=t-e,o=new f(r,void 0,!0),i=0;i<r;i++)o[i]=this[i+e];return o},f.prototype.get=function(e){return console.log(\".get() is deprecated. Access using array indexes instead.\"),this.readUInt8(e)},f.prototype.set=function(e,t){return console.log(\".set() is deprecated. Access using array indexes instead.\"),this.writeUInt8(e,t)},f.prototype.readUInt8=function(e,t){if(t||(d(null!=e,\"missing offset\"),d(e<this.length,\"Trying to read beyond buffer length\")),!(e>=this.length))return this[e]},f.prototype.readUInt16LE=function(e,t){return o(this,e,!0,t)},f.prototype.readUInt16BE=function(e,t){return o(this,e,!1,t)},f.prototype.readUInt32LE=function(e,t){return u(this,e,!0,t)},f.prototype.readUInt32BE=function(e,t){return u(this,e,!1,t)},f.prototype.readInt8=function(e,t){if(t||(d(null!=e,\"missing offset\"),d(e<this.length,\"Trying to read beyond buffer length\")),!(e>=this.length))return 128&this[e]?-1*(255-this[e]+1):this[e]},f.prototype.readInt16LE=function(e,t){return _(this,e,!0,t)},f.prototype.readInt16BE=function(e,t){return _(this,e,!1,t)},f.prototype.readInt32LE=function(e,t){return E(this,e,!0,t)},f.prototype.readInt32BE=function(e,t){return E(this,e,!1,t)},f.prototype.readFloatLE=function(e,t){return I(this,e,!0,t)},f.prototype.readFloatBE=function(e,t){return I(this,e,!1,t)},f.prototype.readDoubleLE=function(e,t){return A(this,e,!0,t)},f.prototype.readDoubleBE=function(e,t){return A(this,e,!1,t)},f.prototype.writeUInt8=function(e,t,n){n||(d(null!=e,\"missing value\"),d(null!=t,\"missing offset\"),d(t<this.length,\"trying to write beyond buffer length\"),Y(e,255)),t>=this.length||(this[t]=e)},f.prototype.writeUInt16LE=function(e,t,n){s(this,e,t,!0,n)},f.prototype.writeUInt16BE=function(e,t,n){s(this,e,t,!1,n)},f.prototype.writeUInt32LE=function(e,t,n){l(this,e,t,!0,n)},f.prototype.writeUInt32BE=function(e,t,n){l(this,e,t,!1,n)},f.prototype.writeInt8=function(e,t,n){n||(d(null!=e,\"missing value\"),d(null!=t,\"missing offset\"),d(t<this.length,\"Trying to write beyond buffer length\"),F(e,127,-128)),t>=this.length||(0<=e?this.writeUInt8(e,t,n):this.writeUInt8(255+e+1,t,n))},f.prototype.writeInt16LE=function(e,t,n){B(this,e,t,!0,n)},f.prototype.writeInt16BE=function(e,t,n){B(this,e,t,!1,n)},f.prototype.writeInt32LE=function(e,t,n){L(this,e,t,!0,n)},f.prototype.writeInt32BE=function(e,t,n){L(this,e,t,!1,n)},f.prototype.writeFloatLE=function(e,t,n){U(this,e,t,!0,n)},f.prototype.writeFloatBE=function(e,t,n){U(this,e,t,!1,n)},f.prototype.writeDoubleLE=function(e,t,n){x(this,e,t,!0,n)},f.prototype.writeDoubleBE=function(e,t,n){x(this,e,t,!1,n)},f.prototype.fill=function(e,t,n){if(t=t||0,n=n||this.length,d(\"number\"==typeof(e=\"string\"==typeof(e=e||0)?e.charCodeAt(0):e)&&!isNaN(e),\"value is not a number\"),d(t<=n,\"end < start\"),n!==t&&0!==this.length){d(0<=t&&t<this.length,\"start out of bounds\"),d(0<=n&&n<=this.length,\"end out of bounds\");for(var r=t;r<n;r++)this[r]=e}},f.prototype.inspect=function(){for(var e=[],t=this.length,n=0;n<t;n++)if(e[n]=k(this[n]),n===H.INSPECT_MAX_BYTES){e[n+1]=\"...\";break}return\"<Buffer \"+e.join(\" \")+\">\"},f.prototype.toArrayBuffer=function(){if(\"undefined\"==typeof Uint8Array)throw new Error(\"Buffer.toArrayBuffer not supported in this browser\");if(f._useTypedArrays)return new f(this).buffer;for(var e=new Uint8Array(this.length),t=0,n=e.length;t<n;t+=1)e[t]=this[t];return e.buffer};var t=f.prototype;function S(e,t,n){return\"number\"!=typeof e?n:t<=(e=~~e)?t:0<=e||0<=(e+=t)?e:0}function j(e){return(e=~~Math.ceil(+e))<0?0:e}function C(e){return(Array.isArray||function(e){return\"[object Array]\"===Object.prototype.toString.call(e)})(e)}function k(e){return e<16?\"0\"+e.toString(16):e.toString(16)}function T(e){for(var t=[],n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<=127)t.push(e.charCodeAt(n));else for(var o=n,i=(55296<=r&&r<=57343&&n++,encodeURIComponent(e.slice(o,n+1)).substr(1).split(\"%\")),u=0;u<i.length;u++)t.push(parseInt(i[u],16))}return t}function M(e){return a.toByteArray(e)}function c(e,t,n,r){for(var o=0;o<r&&!(o+n>=t.length||o>=e.length);o++)t[o+n]=e[o];return o}function N(e){try{return decodeURIComponent(e)}catch(e){return String.fromCharCode(65533)}}function Y(e,t){d(\"number\"==typeof e,\"cannot write a non-number as a number\"),d(0<=e,\"specified a negative value for writing an unsigned value\"),d(e<=t,\"value is larger than maximum value for type\"),d(Math.floor(e)===e,\"value has a fractional component\")}function F(e,t,n){d(\"number\"==typeof e,\"cannot write a non-number as a number\"),d(e<=t,\"value larger than maximum allowed value\"),d(n<=e,\"value smaller than minimum allowed value\"),d(Math.floor(e)===e,\"value has a fractional component\")}function D(e,t,n){d(\"number\"==typeof e,\"cannot write a non-number as a number\"),d(e<=t,\"value larger than maximum allowed value\"),d(n<=e,\"value smaller than minimum allowed value\")}function d(e,t){if(!e)throw new Error(t||\"Failed assertion\")}f._augment=function(e){return e._isBuffer=!0,e._get=e.get,e._set=e.set,e.get=t.get,e.set=t.set,e.write=t.write,e.toString=t.toString,e.toLocaleString=t.toString,e.toJSON=t.toJSON,e.copy=t.copy,e.slice=t.slice,e.readUInt8=t.readUInt8,e.readUInt16LE=t.readUInt16LE,e.readUInt16BE=t.readUInt16BE,e.readUInt32LE=t.readUInt32LE,e.readUInt32BE=t.readUInt32BE,e.readInt8=t.readInt8,e.readInt16LE=t.readInt16LE,e.readInt16BE=t.readInt16BE,e.readInt32LE=t.readInt32LE,e.readInt32BE=t.readInt32BE,e.readFloatLE=t.readFloatLE,e.readFloatBE=t.readFloatBE,e.readDoubleLE=t.readDoubleLE,e.readDoubleBE=t.readDoubleBE,e.writeUInt8=t.writeUInt8,e.writeUInt16LE=t.writeUInt16LE,e.writeUInt16BE=t.writeUInt16BE,e.writeUInt32LE=t.writeUInt32LE,e.writeUInt32BE=t.writeUInt32BE,e.writeInt8=t.writeInt8,e.writeInt16LE=t.writeInt16LE,e.writeInt16BE=t.writeInt16BE,e.writeInt32LE=t.writeInt32LE,e.writeInt32BE=t.writeInt32BE,e.writeFloatLE=t.writeFloatLE,e.writeFloatBE=t.writeFloatBE,e.writeDoubleLE=t.writeDoubleLE,e.writeDoubleBE=t.writeDoubleBE,e.fill=t.fill,e.inspect=t.inspect,e.toArrayBuffer=t.toArrayBuffer,e}}.call(this,O(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},O(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/buffer/index.js\",\"/node_modules/gulp-browserify/node_modules/buffer\")},{\"base64-js\":2,buffer:3,ieee754:10,lYpoI2:11}],4:[function(c,d,e){!function(e,t,a,n,r,o,i,u,s){var a=c(\"buffer\").Buffer,f=4,l=new a(f);l.fill(0);d.exports={hash:function(e,t,n,r){for(var o=t(function(e,t){e.length%f!=0&&(n=e.length+(f-e.length%f),e=a.concat([e,l],n));for(var n,r=[],o=t?e.readInt32BE:e.readInt32LE,i=0;i<e.length;i+=f)r.push(o.call(e,i));return r}(e=a.isBuffer(e)?e:new a(e),r),8*e.length),t=r,i=new a(n),u=t?i.writeInt32BE:i.writeInt32LE,s=0;s<o.length;s++)u.call(i,o[s],4*s,!0);return i}}}.call(this,c(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},c(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/helpers.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{buffer:3,lYpoI2:11}],5:[function(v,e,_){!function(l,c,u,d,h,p,g,y,w){var u=v(\"buffer\").Buffer,e=v(\"./sha\"),t=v(\"./sha256\"),n=v(\"./rng\"),b={sha1:e,sha256:t,md5:v(\"./md5\")},s=64,a=new u(s);function r(e,n){var r=b[e=e||\"sha1\"],o=[];return r||i(\"algorithm:\",e,\"is not yet supported\"),{update:function(e){return u.isBuffer(e)||(e=new u(e)),o.push(e),e.length,this},digest:function(e){var t=u.concat(o),t=n?function(e,t,n){u.isBuffer(t)||(t=new u(t)),u.isBuffer(n)||(n=new u(n)),t.length>s?t=e(t):t.length<s&&(t=u.concat([t,a],s));for(var r=new u(s),o=new u(s),i=0;i<s;i++)r[i]=54^t[i],o[i]=92^t[i];return n=e(u.concat([r,n])),e(u.concat([o,n]))}(r,n,t):r(t);return o=null,e?t.toString(e):t}}}function i(){var e=[].slice.call(arguments).join(\" \");throw new Error([e,\"we accept pull requests\",\"http://github.com/dominictarr/crypto-browserify\"].join(\"\\n\"))}a.fill(0),_.createHash=function(e){return r(e)},_.createHmac=r,_.randomBytes=function(e,t){if(!t||!t.call)return new u(n(e));try{t.call(this,void 0,new u(n(e)))}catch(e){t(e)}};var o,f=[\"createCredentials\",\"createCipher\",\"createCipheriv\",\"createDecipher\",\"createDecipheriv\",\"createSign\",\"createVerify\",\"createDiffieHellman\",\"pbkdf2\"],m=function(e){_[e]=function(){i(\"sorry,\",e,\"is not implemented yet\")}};for(o in f)m(f[o],o)}.call(this,v(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},v(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/index.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{\"./md5\":6,\"./rng\":7,\"./sha\":8,\"./sha256\":9,buffer:3,lYpoI2:11}],6:[function(w,b,e){!function(e,r,o,i,u,a,f,l,y){var t=w(\"./helpers\");function n(e,t){e[t>>5]|=128<<t%32,e[14+(t+64>>>9<<4)]=t;for(var n=1732584193,r=-271733879,o=-1732584194,i=271733878,u=0;u<e.length;u+=16){var s=n,a=r,f=o,l=i,n=c(n,r,o,i,e[u+0],7,-680876936),i=c(i,n,r,o,e[u+1],12,-389564586),o=c(o,i,n,r,e[u+2],17,606105819),r=c(r,o,i,n,e[u+3],22,-1044525330);n=c(n,r,o,i,e[u+4],7,-176418897),i=c(i,n,r,o,e[u+5],12,1200080426),o=c(o,i,n,r,e[u+6],17,-1473231341),r=c(r,o,i,n,e[u+7],22,-45705983),n=c(n,r,o,i,e[u+8],7,1770035416),i=c(i,n,r,o,e[u+9],12,-1958414417),o=c(o,i,n,r,e[u+10],17,-42063),r=c(r,o,i,n,e[u+11],22,-1990404162),n=c(n,r,o,i,e[u+12],7,1804603682),i=c(i,n,r,o,e[u+13],12,-40341101),o=c(o,i,n,r,e[u+14],17,-1502002290),n=d(n,r=c(r,o,i,n,e[u+15],22,1236535329),o,i,e[u+1],5,-165796510),i=d(i,n,r,o,e[u+6],9,-1069501632),o=d(o,i,n,r,e[u+11],14,643717713),r=d(r,o,i,n,e[u+0],20,-373897302),n=d(n,r,o,i,e[u+5],5,-701558691),i=d(i,n,r,o,e[u+10],9,38016083),o=d(o,i,n,r,e[u+15],14,-660478335),r=d(r,o,i,n,e[u+4],20,-405537848),n=d(n,r,o,i,e[u+9],5,568446438),i=d(i,n,r,o,e[u+14],9,-1019803690),o=d(o,i,n,r,e[u+3],14,-187363961),r=d(r,o,i,n,e[u+8],20,1163531501),n=d(n,r,o,i,e[u+13],5,-1444681467),i=d(i,n,r,o,e[u+2],9,-51403784),o=d(o,i,n,r,e[u+7],14,1735328473),n=h(n,r=d(r,o,i,n,e[u+12],20,-1926607734),o,i,e[u+5],4,-378558),i=h(i,n,r,o,e[u+8],11,-2022574463),o=h(o,i,n,r,e[u+11],16,1839030562),r=h(r,o,i,n,e[u+14],23,-35309556),n=h(n,r,o,i,e[u+1],4,-1530992060),i=h(i,n,r,o,e[u+4],11,1272893353),o=h(o,i,n,r,e[u+7],16,-155497632),r=h(r,o,i,n,e[u+10],23,-1094730640),n=h(n,r,o,i,e[u+13],4,681279174),i=h(i,n,r,o,e[u+0],11,-358537222),o=h(o,i,n,r,e[u+3],16,-722521979),r=h(r,o,i,n,e[u+6],23,76029189),n=h(n,r,o,i,e[u+9],4,-640364487),i=h(i,n,r,o,e[u+12],11,-421815835),o=h(o,i,n,r,e[u+15],16,530742520),n=p(n,r=h(r,o,i,n,e[u+2],23,-995338651),o,i,e[u+0],6,-198630844),i=p(i,n,r,o,e[u+7],10,1126891415),o=p(o,i,n,r,e[u+14],15,-1416354905),r=p(r,o,i,n,e[u+5],21,-57434055),n=p(n,r,o,i,e[u+12],6,1700485571),i=p(i,n,r,o,e[u+3],10,-1894986606),o=p(o,i,n,r,e[u+10],15,-1051523),r=p(r,o,i,n,e[u+1],21,-2054922799),n=p(n,r,o,i,e[u+8],6,1873313359),i=p(i,n,r,o,e[u+15],10,-30611744),o=p(o,i,n,r,e[u+6],15,-1560198380),r=p(r,o,i,n,e[u+13],21,1309151649),n=p(n,r,o,i,e[u+4],6,-145523070),i=p(i,n,r,o,e[u+11],10,-1120210379),o=p(o,i,n,r,e[u+2],15,718787259),r=p(r,o,i,n,e[u+9],21,-343485551),n=g(n,s),r=g(r,a),o=g(o,f),i=g(i,l)}return Array(n,r,o,i)}function s(e,t,n,r,o,i){return g((t=g(g(t,e),g(r,i)))<<o|t>>>32-o,n)}function c(e,t,n,r,o,i,u){return s(t&n|~t&r,e,t,o,i,u)}function d(e,t,n,r,o,i,u){return s(t&r|n&~r,e,t,o,i,u)}function h(e,t,n,r,o,i,u){return s(t^n^r,e,t,o,i,u)}function p(e,t,n,r,o,i,u){return s(n^(t|~r),e,t,o,i,u)}function g(e,t){var n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n}b.exports=function(e){return t.hash(e,n,16)}}.call(this,w(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},w(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/md5.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{\"./helpers\":4,buffer:3,lYpoI2:11}],7:[function(e,l,t){!function(e,t,n,r,o,i,u,s,f){var a;l.exports=a||function(e){for(var t,n=new Array(e),r=0;r<e;r++)0==(3&r)&&(t=4294967296*Math.random()),n[r]=t>>>((3&r)<<3)&255;return n}}.call(this,e(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},e(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/rng.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{buffer:3,lYpoI2:11}],8:[function(c,d,e){!function(e,t,n,r,o,s,a,f,l){var i=c(\"./helpers\");function u(l,c){l[c>>5]|=128<<24-c%32,l[15+(c+64>>9<<4)]=c;for(var e,t,n,r=Array(80),o=1732584193,i=-271733879,u=-1732584194,s=271733878,d=-1009589776,h=0;h<l.length;h+=16){for(var p=o,g=i,y=u,w=s,b=d,a=0;a<80;a++){r[a]=a<16?l[h+a]:v(r[a-3]^r[a-8]^r[a-14]^r[a-16],1);var f=m(m(v(o,5),(f=i,t=u,n=s,(e=a)<20?f&t|~f&n:!(e<40)&&e<60?f&t|f&n|t&n:f^t^n)),m(m(d,r[a]),(e=a)<20?1518500249:e<40?1859775393:e<60?-1894007588:-899497514)),d=s,s=u,u=v(i,30),i=o,o=f}o=m(o,p),i=m(i,g),u=m(u,y),s=m(s,w),d=m(d,b)}return Array(o,i,u,s,d)}function m(e,t){var n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n}function v(e,t){return e<<t|e>>>32-t}d.exports=function(e){return i.hash(e,u,20,!0)}}.call(this,c(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},c(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/sha.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{\"./helpers\":4,buffer:3,lYpoI2:11}],9:[function(c,d,e){!function(e,t,n,r,u,s,a,f,l){function b(e,t){var n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n}function o(e,l){var c,d=new Array(1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298),t=new Array(1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225),n=new Array(64);e[l>>5]|=128<<24-l%32,e[15+(l+64>>9<<4)]=l;for(var r,o,h=0;h<e.length;h+=16){for(var i=t[0],u=t[1],s=t[2],p=t[3],a=t[4],g=t[5],y=t[6],w=t[7],f=0;f<64;f++)n[f]=f<16?e[f+h]:b(b(b((o=n[f-2],m(o,17)^m(o,19)^v(o,10)),n[f-7]),(o=n[f-15],m(o,7)^m(o,18)^v(o,3))),n[f-16]),c=b(b(b(b(w,m(o=a,6)^m(o,11)^m(o,25)),a&g^~a&y),d[f]),n[f]),r=b(m(r=i,2)^m(r,13)^m(r,22),i&u^i&s^u&s),w=y,y=g,g=a,a=b(p,c),p=s,s=u,u=i,i=b(c,r);t[0]=b(i,t[0]),t[1]=b(u,t[1]),t[2]=b(s,t[2]),t[3]=b(p,t[3]),t[4]=b(a,t[4]),t[5]=b(g,t[5]),t[6]=b(y,t[6]),t[7]=b(w,t[7])}return t}var i=c(\"./helpers\"),m=function(e,t){return e>>>t|e<<32-t},v=function(e,t){return e>>>t};d.exports=function(e){return i.hash(e,o,32,!0)}}.call(this,c(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},c(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/sha256.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{\"./helpers\":4,buffer:3,lYpoI2:11}],10:[function(e,t,f){!function(e,t,n,r,o,i,u,s,a){f.read=function(e,t,n,r,o){var i,u,l=8*o-r-1,c=(1<<l)-1,d=c>>1,s=-7,a=n?o-1:0,f=n?-1:1,o=e[t+a];for(a+=f,i=o&(1<<-s)-1,o>>=-s,s+=l;0<s;i=256*i+e[t+a],a+=f,s-=8);for(u=i&(1<<-s)-1,i>>=-s,s+=r;0<s;u=256*u+e[t+a],a+=f,s-=8);if(0===i)i=1-d;else{if(i===c)return u?NaN:1/0*(o?-1:1);u+=Math.pow(2,r),i-=d}return(o?-1:1)*u*Math.pow(2,i-r)},f.write=function(e,t,l,n,r,c){var o,i,u=8*c-r-1,s=(1<<u)-1,a=s>>1,d=23===r?Math.pow(2,-24)-Math.pow(2,-77):0,f=n?0:c-1,h=n?1:-1,c=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(i=isNaN(t)?1:0,o=s):(o=Math.floor(Math.log(t)/Math.LN2),t*(n=Math.pow(2,-o))<1&&(o--,n*=2),2<=(t+=1<=o+a?d/n:d*Math.pow(2,1-a))*n&&(o++,n/=2),s<=o+a?(i=0,o=s):1<=o+a?(i=(t*n-1)*Math.pow(2,r),o+=a):(i=t*Math.pow(2,a-1)*Math.pow(2,r),o=0));8<=r;e[l+f]=255&i,f+=h,i/=256,r-=8);for(o=o<<r|i,u+=r;0<u;e[l+f]=255&o,f+=h,o/=256,u-=8);e[l+f-h]|=128*c}}.call(this,e(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},e(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/ieee754/index.js\",\"/node_modules/gulp-browserify/node_modules/ieee754\")},{buffer:3,lYpoI2:11}],11:[function(e,h,t){!function(e,t,n,r,o,f,l,c,d){var i,u,s;function a(){}(e=h.exports={}).nextTick=(u=\"undefined\"!=typeof window&&window.setImmediate,s=\"undefined\"!=typeof window&&window.postMessage&&window.addEventListener,u?function(e){return window.setImmediate(e)}:s?(i=[],window.addEventListener(\"message\",function(e){var t=e.source;t!==window&&null!==t||\"process-tick\"!==e.data||(e.stopPropagation(),0<i.length&&i.shift()())},!0),function(e){i.push(e),window.postMessage(\"process-tick\",\"*\")}):function(e){setTimeout(e,0)}),e.title=\"browser\",e.browser=!0,e.env={},e.argv=[],e.on=a,e.addListener=a,e.once=a,e.off=a,e.removeListener=a,e.removeAllListeners=a,e.emit=a,e.binding=function(e){throw new Error(\"process.binding is not supported\")},e.cwd=function(){return\"/\"},e.chdir=function(e){throw new Error(\"process.chdir is not supported\")}}.call(this,e(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},e(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/process/browser.js\",\"/node_modules/gulp-browserify/node_modules/process\")},{buffer:3,lYpoI2:11}]},{},[1])(1)});", "module.exports = function pad (num, size) {\n var s = '000000000' + num;\n return s.substr(s.length - size);\n};\n", "var pad = require('./pad.js');\n\nvar env = typeof window === 'object' ? window : self;\nvar globalCount = Object.keys(env).length;\nvar mimeTypesLength = navigator.mimeTypes ? navigator.mimeTypes.length : 0;\nvar clientId = pad((mimeTypesLength +\n navigator.userAgent.length).toString(36) +\n globalCount.toString(36), 4);\n\nmodule.exports = function fingerprint () {\n return clientId;\n};\n", "\nvar getRandomValue;\n\nvar crypto = typeof window !== 'undefined' &&\n (window.crypto || window.msCrypto) ||\n typeof self !== 'undefined' &&\n self.crypto;\n\nif (crypto) {\n var lim = Math.pow(2, 32) - 1;\n getRandomValue = function () {\n return Math.abs(crypto.getRandomValues(new Uint32Array(1))[0] / lim);\n };\n} else {\n getRandomValue = Math.random;\n}\n\nmodule.exports = getRandomValue;\n", "/**\n * cuid.js\n * Collision-resistant UID generator for browsers and node.\n * Sequential for fast db lookups and recency sorting.\n * Safe for element IDs and server-side lookups.\n *\n * Extracted from CLCTR\n *\n * Copyright (c) Eric Elliott 2012\n * MIT License\n */\n\nvar fingerprint = require('./lib/fingerprint.js');\nvar pad = require('./lib/pad.js');\nvar getRandomValue = require('./lib/getRandomValue.js');\n\nvar c = 0,\n blockSize = 4,\n base = 36,\n discreteValues = Math.pow(base, blockSize);\n\nfunction randomBlock () {\n return pad((getRandomValue() *\n discreteValues << 0)\n .toString(base), blockSize);\n}\n\nfunction safeCounter () {\n c = c < discreteValues ? c : 0;\n c++; // this is not subliminal\n return c - 1;\n}\n\nfunction cuid () {\n // Starting with a lowercase letter makes\n // it HTML element ID friendly.\n var letter = 'c', // hard-coded allows for sequential access\n\n // timestamp\n // warning: this exposes the exact date and time\n // that the uid was created.\n timestamp = (new Date().getTime()).toString(base),\n\n // Prevent same-machine collisions.\n counter = pad(safeCounter().toString(base), blockSize),\n\n // A few chars to generate distinct ids for different\n // clients (so different computers are far less\n // likely to generate the same id)\n print = fingerprint(),\n\n // Grab some more chars from Math.random()\n random = randomBlock() + randomBlock();\n\n return letter + timestamp + counter + print + random;\n}\n\ncuid.slug = function slug () {\n var date = new Date().getTime().toString(36),\n counter = safeCounter().toString(36).slice(-4),\n print = fingerprint().slice(0, 1) +\n fingerprint().slice(-1),\n random = randomBlock().slice(-2);\n\n return date.slice(-2) +\n counter + print + random;\n};\n\ncuid.isCuid = function isCuid (stringToCheck) {\n if (typeof stringToCheck !== 'string') return false;\n if (stringToCheck.startsWith('c')) return true;\n return false;\n};\n\ncuid.isSlug = function isSlug (stringToCheck) {\n if (typeof stringToCheck !== 'string') return false;\n var stringLength = stringToCheck.length;\n if (stringLength >= 7 && stringLength <= 10) return true;\n return false;\n};\n\ncuid.fingerprint = fingerprint;\n\nmodule.exports = cuid;\n", "/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n function next() {\n while (env.stack.length) {\n var rec = env.stack.pop();\n try {\n var result = rec.dispose && rec.dispose.call(rec.value);\n if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n catch (e) {\n fail(e);\n }\n }\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n};\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=typed-event-interfaces.js.map", null, null, null, null, null, null, null, null, "import { Client } from './client/Client.js';\nimport type { ContextInit } from './context/context.js';\nexport type { ClientWithCollections } from './client/Client.js';\nexport { Client, type ClientDescriptorOptions, type ClientInitOptions };\ntype ClientInitOptions = ContextInit;\n/** @deprecated - use ClientInitOptions alias */\ntype ClientDescriptorOptions = ClientInitOptions;\n// backward compat\nexport { createMigration, schema } from '@verdant-web/common';\nexport type {\n\tCollectionFilter,\n\tDocumentBaseline,\n\tFileData,\n\tIndexValueTag,\n\tMigration,\n\tObjectIdentifier,\n\tStorageAnyFieldSchema,\n\tStorageArrayFieldSchema,\n\tStorageBooleanFieldSchema,\n\tStorageCollectionSchema,\n\tStorageDocument,\n\tStorageFieldSchema,\n\tStorageFieldsSchema,\n\tStorageFileFieldSchema,\n\tStorageMapFieldSchema,\n\tStorageNumberFieldSchema,\n\tStorageObjectFieldSchema,\n\tStorageSchema,\n\tStorageStringFieldSchema,\n\tUserInfo,\n\tVerdantError,\n\tVerdantErrorCode,\n} from '@verdant-web/common';\nexport * from './authorization.js';\nexport { Entity, getEntityClient } from './entities/Entity.js';\nexport type {\n\tAccessibleEntityProperty,\n\tAnyEntity,\n\tEntityDestructured,\n\tEntityInit,\n\tEntityShape,\n\tListEntity,\n\tObjectEntity,\n} from './entities/types.js';\nexport { EntityFile, type EntityFileSnapshot } from './files/EntityFile.js';\nexport * from './logger.js';\nexport { IdbPersistence } from './persistence/idb/idbPersistence.js';\nexport type * from './persistence/interfaces.js';\nexport type { QueryStatus } from './queries/BaseQuery.js';\nexport type { CollectionQueries } from './queries/CollectionQueries.js';\nexport type { Query } from './queries/types.js';\nexport * from './sync/cliSync.js';\nexport { ServerSync, type ServerSyncOptions } from './sync/Sync.js';\nexport type { SyncTransportMode } from './sync/Sync.js';\nexport { UndoHistory } from './UndoHistory.js';\nexport * from './utils/id.js';\nexport { Client as Storage };\n", "import { DocumentBaseline } from './baseline.js';\nimport { Operation } from './operation.js';\n\nfunction encode(str: string): AuthorizationKey {\n\tif (typeof Buffer !== 'undefined') {\n\t\tconst val = Buffer.from(str).toString('base64');\n\t\treturn val as AuthorizationKey;\n\t}\n\tconst val = btoa(str);\n\treturn val as AuthorizationKey;\n}\n\nfunction decode(str: string): string {\n\tif (typeof Buffer !== 'undefined') {\n\t\treturn Buffer.from(str, 'base64').toString();\n\t}\n\treturn atob(str);\n}\n\nexport type AuthorizationKey = string & {\n\t// virtual type only used for type checking to try to sort\n\t// out between encoded and decoded string values.\n\t'@@type': 'authz';\n};\n\nexport const authz = {\n\tonlyUser: (userId: string): AuthorizationKey => encode(`u:${userId}:*`),\n\tonlyMe: (): AuthorizationKey => authz.onlyUser(ORIGINATOR_SUBJECT),\n\tdecode: (encoded: string) => {\n\t\tconst decoded = decode(encoded);\n\t\tconst parts = decoded.split(':');\n\t\tif (parts.length !== 3) {\n\t\t\tthrow new Error('Invalid authz string');\n\t\t}\n\t\treturn {\n\t\t\tscope: parts[0],\n\t\t\tsubject: parts[1],\n\t\t\taction: parts[2],\n\t\t};\n\t},\n};\n\nexport const ORIGINATOR_SUBJECT = '$$_originator_$$';\n\n/**\n * Rewrites the special \"originator\" constant subject (used by\n * local-only clients) to the given user ID.\n *\n * Used to initialize a library from a local-only replica\n */\nexport function rewriteAuthzOriginator(\n\tdata: { operations?: Operation[]; baselines?: DocumentBaseline[] },\n\tnewSubject: string,\n) {\n\tconst { operations, baselines } = data;\n\tif (operations) {\n\t\tfor (const op of operations) {\n\t\t\tif (op.authz) {\n\t\t\t\tconst decoded = authz.decode(op.authz);\n\t\t\t\tif (decoded.subject === ORIGINATOR_SUBJECT) {\n\t\t\t\t\top.authz = authz.onlyUser(newSubject);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif (baselines) {\n\t\tfor (const baseline of baselines) {\n\t\t\tif (baseline.authz) {\n\t\t\t\tconst decoded = authz.decode(baseline.authz);\n\t\t\t\tif (decoded.subject === ORIGINATOR_SUBJECT) {\n\t\t\t\t\tbaseline.authz = authz.onlyUser(newSubject);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n", "export class Batcher<T, UserData = any> {\n\tprivate batches: Map<string, Batch<T, UserData>> = new Map();\n\n\tconstructor(\n\t\tprivate flusher: (items: T[], batchKey: string, userData: UserData) => any,\n\t) {}\n\n\tadd({\n\t\tkey,\n\t\tuserData,\n\t\titems,\n\t\tmax,\n\t\ttimeout,\n\t}: {\n\t\tkey: string;\n\t\tuserData?: UserData;\n\t\titems: T[];\n\t\tmax?: number | null;\n\t\ttimeout?: number | null;\n\t}) {\n\t\tlet batch = this.batches.get(key);\n\t\tif (!batch) {\n\t\t\tbatch = new Batch({\n\t\t\t\tmax: max || null,\n\t\t\t\tstartedAt: Date.now(),\n\t\t\t\tuserData,\n\t\t\t\ttimeout: timeout || null,\n\t\t\t\tflusher: this.flusher,\n\t\t\t\tkey,\n\t\t\t});\n\t\t\tthis.batches.set(key, batch);\n\t\t}\n\t\tbatch.update({\n\t\t\titems,\n\t\t\tmax,\n\t\t\ttimeout,\n\t\t\tuserData,\n\t\t});\n\n\t\treturn batch;\n\t}\n\n\tflush = (key: string) => {\n\t\tconst batch = this.batches.get(key);\n\t\tif (!batch) return;\n\n\t\treturn batch.flush();\n\t};\n\n\tdiscard = (key: string) => {\n\t\tconst batch = this.batches.get(key);\n\t\tif (!batch) return;\n\n\t\tbatch.discard();\n\t\tthis.batches.delete(key);\n\t};\n\n\tflushAll = () => {\n\t\treturn [...this.batches.values()].map((batch) => batch.flush());\n\t};\n\n\tgetSize = (key: string) => {\n\t\tconst batch = this.batches.get(key);\n\t\tif (!batch) return 0;\n\n\t\treturn batch.items.length;\n\t};\n}\n\nexport class Batch<T, UserData = any> {\n\titems: Array<T> = [];\n\tmax: number | null;\n\tstartedAt: number;\n\ttimeout: number | null;\n\tflushTimeout?: NodeJS.Timeout;\n\tuserData?: any;\n\tflusher: (items: T[], batchKey: string, userData: UserData) => any;\n\tkey: string;\n\n\tconstructor({\n\t\tmax,\n\t\tstartedAt,\n\t\ttimeout,\n\t\tuserData,\n\t\tflusher,\n\t\tkey,\n\t}: {\n\t\tkey: string;\n\t\tmax: number | null;\n\t\tstartedAt: number;\n\t\ttimeout: number | null;\n\t\tuserData?: UserData;\n\t\tflusher: (items: T[], batchKey: string, userData: UserData) => any;\n\t}) {\n\t\tthis.max = max;\n\t\tthis.startedAt = startedAt;\n\t\tthis.timeout = timeout;\n\t\tthis.userData = userData;\n\t\tthis.flusher = flusher;\n\t\tthis.key = key;\n\t}\n\n\tupdate = ({\n\t\titems,\n\t\tmax,\n\t\ttimeout,\n\t\tuserData,\n\t}: {\n\t\titems: Array<T>;\n\t\tmax?: number | null;\n\t\ttimeout?: number | null;\n\t\tuserData?: UserData;\n\t}) => {\n\t\tthis.items.push(...items);\n\t\tif (max !== undefined) this.max = max;\n\t\tif (timeout !== undefined) this.timeout = timeout;\n\t\tif (userData) this.userData = userData;\n\n\t\t// if the batch has items and a timeout but has not\n\t\t// scheduled yet, schedule it\n\t\tconst needsSchedule =\n\t\t\tthis.items.length !== 0 && this.timeout !== null && !this.flushTimeout;\n\n\t\t// if the batch has already reached its max, skip scheduling\n\t\t// and flush immediately\n\t\tif (this.max !== null && this.items.length >= this.max) {\n\t\t\tthis.flush();\n\t\t} else if (needsSchedule && this.timeout !== null) {\n\t\t\tthis.flushTimeout = setTimeout(this.flush, this.timeout);\n\t\t}\n\t};\n\n\tflush = () => {\n\t\tthis.flushTimeout && clearTimeout(this.flushTimeout);\n\t\tthis.flushTimeout = undefined;\n\t\tconst items = this.items;\n\t\tthis.items = [];\n\t\treturn this.flusher(items, this.key, this.userData);\n\t};\n\n\tdiscard = () => {\n\t\tthis.flushTimeout && clearTimeout(this.flushTimeout);\n\t\tthis.flushTimeout = undefined;\n\t\tthis.items = [];\n\t};\n}\n", "export enum VerdantErrorCode {\n\tInvalidRequest = 4000,\n\tBodyRequired = 4001,\n\tNoToken = 4010,\n\tInvalidToken = 4011,\n\tTokenExpired = 4012,\n\tForbidden = 4030,\n\tNotFound = 4040,\n\tUnexpected = 5000,\n\tConfigurationError = 5010,\n\tNoFileStorage = 5011,\n\n\t// Client errors\n\n\tMigrationPathNotFound = 7001,\n\tImportFailed = 7002,\n\t// some functionality was invoked which requires online status, and\n\t// client couldn't connect.\n\tOffline = 7003,\n}\n\nexport class VerdantError extends Error {\n\tstatic Code = VerdantErrorCode;\n\n\tconstructor(\n\t\tpublic code: VerdantErrorCode,\n\t\tcause?: Error | undefined,\n\t\tmessage?: string,\n\t) {\n\t\tsuper(message ?? `Verdant error: ${code}`, {\n\t\t\tcause,\n\t\t});\n\t}\n\n\tget httpStatus() {\n\t\tconst status = Math.floor(this.code / 10);\n\t\tif (status < 600) {\n\t\t\treturn status;\n\t\t}\n\t\treturn 500;\n\t}\n\n\ttoResponse = () => {\n\t\treturn JSON.stringify({\n\t\t\tcode: this.code,\n\t\t});\n\t};\n}\n\nexport function isVerdantErrorResponse(body: any): body is { code: number } {\n\treturn (\n\t\ttypeof body === 'object' && 'code' in body && typeof body.code === 'number'\n\t);\n}\n", "// Unique ID creation requires a high quality random # generator. In the browser we therefore\n// require the crypto API and do not support built-in fallback to lower quality random number\n// generators (like Math.random()).\nvar getRandomValues;\nvar rnds8 = new Uint8Array(16);\nexport default function rng() {\n // lazy load so that environments that need to polyfill have a chance to do so\n if (!getRandomValues) {\n // getRandomValues needs to be invoked in a context where \"this\" is a Crypto implementation. Also,\n // find the complete implementation of crypto (msCrypto) on IE11.\n getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);\n\n if (!getRandomValues) {\n throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');\n }\n }\n\n return getRandomValues(rnds8);\n}", "export default /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;", "import REGEX from './regex.js';\n\nfunction validate(uuid) {\n return typeof uuid === 'string' && REGEX.test(uuid);\n}\n\nexport default validate;", "import validate from './validate.js';\n/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\n\nvar byteToHex = [];\n\nfor (var i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).substr(1));\n}\n\nfunction stringify(arr) {\n var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n // Note: Be careful editing this code! It's been tuned for performance\n // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434\n var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one\n // of the following:\n // - One or more input array values don't map to a hex octet (leading to\n // \"undefined\" in the uuid)\n // - Invalid input values for the RFC `version` or `variant` fields\n\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n\n return uuid;\n}\n\nexport default stringify;", "import rng from './rng.js';\nimport stringify from './stringify.js';\n\nfunction v4(options, buf, offset) {\n options = options || {};\n var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n\n rnds[6] = rnds[6] & 0x0f | 0x40;\n rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided\n\n if (buf) {\n offset = offset || 0;\n\n for (var i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n\n return buf;\n }\n\n return stringify(rnds);\n}\n\nexport default v4;", "import hash from 'object-hash';\nimport { v4 } from 'uuid';\nimport { assignOid, maybeGetOid } from './oids.js';\n\nexport function take<T extends object, Keys extends keyof T>(\n\tobj: T,\n\tkeys: Keys[],\n): Pick<T, Keys> {\n\tconst result: any = {};\n\tfor (const key of keys) {\n\t\tresult[key] = obj[key];\n\t}\n\treturn result;\n}\n\nexport function omit<T extends object, Keys extends keyof T>(\n\tobj: T,\n\tkeys: Keys[],\n): Omit<T, Keys> {\n\tconst result: any = {};\n\tfor (const key of Object.keys(obj)) {\n\t\tif (!keys.includes(key as Keys)) {\n\t\t\tresult[key] = (obj as any)[key];\n\t\t}\n\t}\n\treturn result;\n}\n\nexport function getSortedIndex<T>(\n\tarray: T[],\n\tinsert: T,\n\tcompare: (a: T, b: T) => number,\n) {\n\tlet low = 0;\n\tlet high = array.length;\n\twhile (low < high) {\n\t\tconst mid = (low + high) >>> 1;\n\t\tconst cmp = compare(array[mid], insert);\n\t\tif (cmp < 0) {\n\t\t\tlow = mid + 1;\n\t\t} else {\n\t\t\thigh = mid;\n\t\t}\n\t}\n\treturn low;\n}\n\nfunction orderedReplacer(k: any, v: any) {\n\tif (typeof v !== 'object' || v === null || Array.isArray(v)) {\n\t\treturn v;\n\t}\n\treturn Object.fromEntries(\n\t\tObject.entries(v).sort(([ka], [kb]) => (ka < kb ? -1 : ka > kb ? 1 : 0)),\n\t);\n}\n/**\n * Consistently stringifies an object regardless\n * of key insertion order\n */\nexport function stableStringify(obj: any) {\n\tconst seen = new WeakMap();\n\tlet cyclicCount = 0;\n\treturn JSON.stringify(obj, (k, v) => {\n\t\tif (typeof v === 'object' && v !== null) {\n\t\t\tif (seen.has(v)) {\n\t\t\t\treturn { $ref: seen.get(v) };\n\t\t\t}\n\t\t\tseen.set(v, `cyclic-ref:${cyclicCount++}`);\n\t\t}\n\t\treturn orderedReplacer(k, v);\n\t});\n}\n\n/**\n * A version of structured cloning which preserves object identity\n * references in the system.\n */\nexport function cloneDeep<T>(obj: T, copyOids = true): T {\n\t// shortcut... if OIDs aren't important, we can use the built-in\n\t// structured cloning algorithm which should be faster.\n\tif (!copyOids && typeof structuredClone === 'function') {\n\t\treturn structuredClone(obj);\n\t}\n\n\tif (isObject(obj) || Array.isArray(obj)) {\n\t\tconst oid = maybeGetOid(obj);\n\t\tlet clone: any;\n\t\tif (Array.isArray(obj)) {\n\t\t\tclone = obj.map((v) => cloneDeep(v, copyOids)) as T;\n\t\t} else {\n\t\t\tclone = {};\n\t\t\tfor (const [key, value] of Object.entries(obj as any)) {\n\t\t\t\tclone[key] = cloneDeep(value, copyOids);\n\t\t\t}\n\t\t}\n\t\tif (copyOids && oid) {\n\t\t\tassignOid(clone, oid);\n\t\t}\n\t\treturn clone;\n\t}\n\treturn obj;\n}\n\n// TODO: better hash\nexport function hashObject(obj: any) {\n\t// hash the object into a unique string\n\treturn hash(obj);\n}\n\nexport function isObject(obj: any) {\n\treturn obj && typeof obj === 'object';\n}\n\nexport function roughSizeOfObject(object: any) {\n\tvar objectList = [];\n\tvar stack = [object];\n\tvar bytes = 0;\n\n\twhile (stack.length) {\n\t\tvar value = stack.pop();\n\n\t\tif (typeof value === 'boolean') {\n\t\t\tbytes += 4;\n\t\t} else if (typeof value === 'string') {\n\t\t\tbytes += value.length * 2;\n\t\t} else if (typeof value === 'number') {\n\t\t\tbytes += 8;\n\t\t} else if (typeof value === 'object' && objectList.indexOf(value) === -1) {\n\t\t\tobjectList.push(value);\n\n\t\t\tfor (var i in value) {\n\t\t\t\tstack.push(value[i]);\n\t\t\t}\n\t\t}\n\t}\n\treturn bytes;\n}\n\nexport function assert(\n\tcondition: any,\n\tmessage: string = 'assertion failed',\n): asserts condition {\n\tif (!condition) {\n\t\tthrow new Error(message);\n\t}\n}\n\nexport function generateId(length = 16) {\n\treturn v4().replace('-', '').slice(0, length);\n}\n\nexport function findLastIndex<T>(array: T[], predicate: (item: T) => boolean) {\n\tfor (let i = array.length - 1; i >= 0; i--) {\n\t\tif (predicate(array[i])) {\n\t\t\treturn i;\n\t\t}\n\t}\n\treturn -1;\n}\n\nexport function debounce<T extends (...args: any[]) => any>(\n\tfn: T,\n\twait: number,\n): T {\n\tlet timeout: any;\n\treturn function (this: any, ...args: any[]) {\n\t\tconst context = this;\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(() => fn.apply(context, args), wait);\n\t} as any;\n}\n\nexport function throttle<T extends (...args: any[]) => any>(\n\tfn: T,\n\twait: number,\n): T {\n\tlet lastTime = 0;\n\n\t// invoke once for the last call\n\tlet trailingTimeout: any;\n\n\treturn function (this: any, ...args: any[]) {\n\t\tconst context = this;\n\t\tconst now = Date.now();\n\t\tif (now - lastTime >= wait) {\n\t\t\tlastTime = now;\n\t\t\tfn.apply(context, args);\n\t\t\tclearTimeout(trailingTimeout);\n\t\t} else {\n\t\t\tclearTimeout(trailingTimeout);\n\t\t\ttrailingTimeout = setTimeout(() => {\n\t\t\t\tlastTime = now;\n\t\t\t\tfn.apply(context, args);\n\t\t\t}, wait);\n\t\t}\n\t} as any;\n}\n\nexport function noop() {}\n\n// avoids recursion and other issues with JSON.stringify\nexport function safeStringify(obj: any) {\n\ttry {\n\t\treturn JSON.stringify(obj);\n\t} catch (e) {\n\t\treturn `[recursive/invalid:${String(obj)}]`;\n\t}\n}\n", "import { isObject } from './utils.js';\n\nexport type FileRef = {\n\t'@@type': 'file';\n\tid: string;\n};\n\nexport function isFileRef(value: any): value is FileRef {\n\treturn value && value['@@type'] === 'file';\n}\nexport function createFileRef(id: string): FileRef {\n\treturn {\n\t\t'@@type': 'file',\n\t\tid,\n\t};\n}\n\nexport type FileData = {\n\tid: string;\n\t/**\n\t * For locally created files, this starts false, until it's uploaded\n\t * Remote files this is always true\n\t */\n\tremote: boolean;\n\tname: string;\n\ttype: string;\n\t/** A local File instance, if available. */\n\tfile?: Blob | null;\n\t/** The server URL of this file. */\n\turl?: string | null;\n\t/** Local filesystem path for the file. Only used in environments with direct fs access. */\n\tlocalPath?: string;\n\t/** The time this file was added, if available. */\n\ttimestamp?: string;\n};\n\nexport function getAllFileFields(snapshot: any): [string, FileRef][] {\n\treturn Object.entries(snapshot).filter((entry) => isFileRef(entry[1])) as [\n\t\tstring,\n\t\tFileRef,\n\t][];\n}\n\nexport function isFile(value: any) {\n\tif (typeof File !== 'undefined' && value instanceof File) {\n\t\treturn true;\n\t}\n\tif (typeof Blob !== 'undefined' && value instanceof Blob) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nexport function isFileData(value: any): value is FileData {\n\treturn (\n\t\tvalue &&\n\t\tisObject(value) &&\n\t\ttypeof value.id === 'string' &&\n\t\ttypeof value.remote === 'boolean' &&\n\t\ttypeof value.name === 'string' &&\n\t\ttypeof value.type === 'string'\n\t);\n}\n", "import { FileRef, isFileRef } from './files.js';\nimport { isObjectRef, ObjectRef } from './operation.js';\n\nexport function isRef(obj: any): obj is ObjectRef | FileRef {\n\treturn isObjectRef(obj) || isFileRef(obj);\n}\n\nexport function compareRefs(a: any, b: any) {\n\tif (a === b) return true;\n\tif (!isRef(a) || !isRef(b)) return false;\n\tif (a['@@type'] !== b['@@type']) return false;\n\tif (a.id !== b.id) return false;\n\treturn true;\n}\n\nexport type Ref = ObjectRef | FileRef;\n\nexport function makeObjectRef(oid: string): ObjectRef {\n\treturn { '@@type': 'ref', id: oid };\n}\n\nexport function makeFileRef(oid: string): FileRef {\n\treturn { '@@type': 'file', id: oid };\n}\n", "import { AuthorizationKey } from './authz.js';\nimport { DocumentBaseline } from './baseline.js';\nimport { FileRef, isFileRef } from './files.js';\nimport {\n\tassignOid,\n\tassignOidsToAllSubObjects,\n\tgetOid,\n\tgetOidRoot,\n\tmaybeGetOid,\n\tnormalize,\n\tObjectIdentifier,\n\tremoveOid,\n} from './oids.js';\nimport { compareRefs, isRef } from './refs.js';\nimport { assert, cloneDeep, findLastIndex, isObject } from './utils.js';\n\n// export type ObjectIdentifier<\n// \tCollectionName extends string = string,\n// \tDocumentId extends string = string,\n// \tDocumentOid extends string = string,\n// > =\n// \t| `${CollectionName}/${DocumentId}:${DocumentOid}`\n// \t| `${CollectionName}/${DocumentId}:${DocumentOid}#${string}`;\n\nexport type ObjectRef = {\n\t'@@type': 'ref';\n\tid: ObjectIdentifier;\n};\n\nexport function isObjectRef(obj: any): obj is ObjectRef {\n\treturn obj && typeof obj === 'object' && obj['@@type'] === 'ref';\n}\n\nexport type Normalized<T> = {\n\t[key in keyof T]: T[key] extends Object ? ObjectRef : T[key];\n};\n\n// patches v2\n\nexport type PropertyName = string | number;\n/**\n * List patches can target a particular child list or\n * nested lists. The first path item is the property path\n * of the first child list, any subsequent values are nested\n * list indices.\n */\nexport type PropertyValue =\n\t| string\n\t| number\n\t| boolean\n\t| null\n\t| undefined\n\t| ObjectRef\n\t| FileRef;\n\n// all patches refer to a specific sub-object.\ninterface BaseOperationPatch {}\n\nexport interface OperationPatchInitialize extends BaseOperationPatch {\n\top: 'initialize';\n\tvalue: any;\n}\nexport interface OperationPatchSet extends BaseOperationPatch {\n\top: 'set';\n\tname: PropertyName;\n\tvalue: PropertyValue;\n}\nexport interface OperationPatchRemove extends BaseOperationPatch {\n\top: 'remove';\n\tname: PropertyName;\n}\nexport interface OperationPatchListSet extends BaseOperationPatch {\n\top: 'list-set';\n\tindex: number;\n\tvalue: PropertyValue;\n}\nexport interface OperationPatchListPush extends BaseOperationPatch {\n\top: 'list-push';\n\tvalue: PropertyValue;\n}\nexport interface OperationPatchListInsert extends BaseOperationPatch {\n\top: 'list-insert';\n\tindex: number;\n\tvalue?: PropertyValue;\n\tvalues?: PropertyValue[];\n}\nexport interface OperationPatchListDelete extends BaseOperationPatch {\n\top: 'list-delete';\n\tindex: number;\n\tcount: number;\n}\n/**\n * Optimal for lists of object references. Moves\n * the selected item to the target index even if it\n * is not at the original index anymore.\n */\nexport interface OperationPatchListMoveByRef extends BaseOperationPatch {\n\top: 'list-move-by-ref';\n\tvalue: ObjectRef | FileRef;\n\tindex: number;\n}\n/**\n * Suitable for any list move, whether object lists\n * or primitive lists.\n */\nexport interface OperationPatchListMoveByIndex extends BaseOperationPatch {\n\top: 'list-move-by-index';\n\tfrom: number;\n\tto: number;\n}\n/**\n * Removes all instances of the value from\n * the list. Good for set behavior or removing\n * a specific item even if it changes index\n * from conflicts.\n */\nexport interface OperationPatchListRemove extends BaseOperationPatch {\n\top: 'list-remove';\n\tvalue: PropertyValue;\n\tonly?: 'first' | 'last';\n}\n\nexport interface OperationPatchListAdd extends BaseOperationPatch {\n\top: 'list-add';\n\tvalue: PropertyValue;\n}\n\nexport interface OperationPatchDelete extends BaseOperationPatch {\n\top: 'delete';\n}\n\nexport interface OperationPatchTouch extends BaseOperationPatch {\n\top: 'touch';\n}\n\nexport type OperationPatch =\n\t| OperationPatchInitialize\n\t| OperationPatchSet\n\t| OperationPatchRemove\n\t| OperationPatchListSet\n\t| OperationPatchListPush\n\t| OperationPatchListInsert\n\t| OperationPatchListDelete\n\t| OperationPatchListMoveByRef\n\t| OperationPatchListMoveByIndex\n\t| OperationPatchListRemove\n\t| OperationPatchDelete\n\t| OperationPatchListAdd\n\t| OperationPatchTouch;\n\nexport type Operation = {\n\toid: ObjectIdentifier;\n\ttimestamp: string;\n\tdata: OperationPatch;\n\tauthz?: AuthorizationKey;\n};\n\n/**\n * Takes a basic object and constructs a patch list to create it and\n * all of its nested objects.\n */\nexport function initialToPatches(\n\tinitial: any,\n\trootOid: ObjectIdentifier,\n\tgetNow: () => string,\n\tcreateSubId?: () => string,\n\tpatches: Operation[] = [],\n\toptions?: { authz?: AuthorizationKey },\n) {\n\tassignOid(initial, rootOid);\n\tassignOidsToAllSubObjects(initial, createSubId);\n\tconst normalized = normalize(initial);\n\tfor (const key of normalized.keys()) {\n\t\tconst value = normalized.get(key);\n\t\tconst op: Operation = {\n\t\t\toid: key,\n\t\t\ttimestamp: getNow(),\n\t\t\tdata: {\n\t\t\t\top: 'initialize',\n\t\t\t\tvalue: removeOid(value),\n\t\t\t},\n\t\t};\n\t\tpatches.push(addAuthzToOp(op, options?.authz));\n\t}\n\treturn patches;\n}\n\nexport function shallowInitialToPatches(\n\tinitial: any,\n\trootOid: ObjectIdentifier,\n\tgetNow: () => string,\n\tpatches: Operation[] = [],\n\toptions?: { authz?: AuthorizationKey },\n) {\n\tconst op: Operation = {\n\t\toid: rootOid,\n\t\ttimestamp: getNow(),\n\t\tdata: {\n\t\t\top: 'initialize',\n\t\t\tvalue: initial,\n\t\t},\n\t};\n\tpatches.push(addAuthzToOp(op, options?.authz));\n\treturn patches;\n}\n\n// saves a bit of network traffic by not attaching authz\n// key at all if not present\nexport function addAuthzToOp(op: Operation, authz?: AuthorizationKey) {\n\tif (authz) {\n\t\top.authz = authz;\n\t}\n\treturn op;\n}\n\nexport function groupPatchesByOid(patches: Operation[]) {\n\tconst grouped: Record<ObjectIdentifier, Operation[]> = {};\n\tfor (const patch of patches) {\n\t\tif (patch.oid in grouped) {\n\t\t\tgrouped[patch.oid].push(patch);\n\t\t} else {\n\t\t\tgrouped[patch.oid] = [patch];\n\t\t}\n\t}\n\treturn grouped;\n}\n\nexport function groupPatchesByRootOid(patches: Operation[]) {\n\tconst grouped: Record<ObjectIdentifier, Operation[]> = {};\n\tfor (const patch of patches) {\n\t\tconst root = getOidRoot(patch.oid);\n\t\tif (root in grouped) {\n\t\t\tgrouped[root].push(patch);\n\t\t} else {\n\t\t\tgrouped[root] = [patch];\n\t\t}\n\t}\n\treturn grouped;\n}\n\nexport function groupBaselinesByRootOid(baselines: DocumentBaseline[]) {\n\tconst grouped: Record<ObjectIdentifier, DocumentBaseline[]> = {};\n\tfor (const patch of baselines) {\n\t\tconst root = getOidRoot(patch.oid);\n\t\tif (root in grouped) {\n\t\t\tgrouped[root].push(patch);\n\t\t} else {\n\t\t\tgrouped[root] = [patch];\n\t\t}\n\t}\n\treturn grouped;\n}\n\nexport type NormalizedObject =\n\t| {\n\t\t\t[key: PropertyName]: PropertyValue;\n\t }\n\t| Array<PropertyValue>;\n\nfunction listCheck(obj: any, patch: OperationPatch): obj is Array<unknown> {\n\tif (!Array.isArray(obj)) {\n\t\tif (obj === undefined) {\n\t\t\tconsole.error(\n\t\t\t\t`Cannot apply list patch; expected array, received ${JSON.stringify(\n\t\t\t\t\tobj,\n\t\t\t\t)}. This suggests your data is changing from a list to an object over time. (OID: ${maybeGetOid(\n\t\t\t\t\tobj,\n\t\t\t\t)})\\nPatch that was not applied: ${JSON.stringify(patch)}`,\n\t\t\t);\n\t\t}\n\t\treturn false;\n\t} else {\n\t\treturn true;\n\t}\n}\n\n/**\n * The incoming object should already be normalized!\n * This function will mutate the base object.\n */\nexport function applyPatch<T extends NormalizedObject>(\n\tbase: T | undefined,\n\tpatch: OperationPatch,\n\t/**\n\t * Optionally supply a list to which any refs which\n\t * are removed during the patch will be appended.\n\t */\n\tdeletedRefs?: (FileRef | ObjectRef)[],\n): T | undefined {\n\t// deleted objects are represented by undefined\n\t// and remain deleted unless re-initialized\n\tif ((base === undefined || base === null) && patch.op !== 'initialize') {\n\t\treturn base;\n\t}\n\t// ditch typing internally.\n\tconst baseAsAny = base as any;\n\tlet index;\n\tlet spliceResult: any[];\n\n\t// a helper, pass it a value which is about\n\t// to be removed and it will append it to the list\n\t// if it was a ref\n\tfunction checkRef(field: any) {\n\t\t// don't bother if not supplied\n\t\tif (!deletedRefs) return;\n\t\tif (isRef(field)) {\n\t\t\tdeletedRefs.push(field);\n\t\t}\n\t}\n\n\tswitch (patch.op) {\n\t\tcase 'set':\n\t\t\tcheckRef(baseAsAny[patch.name]);\n\t\t\tbaseAsAny[patch.name] = patch.value;\n\t\t\tbreak;\n\t\tcase 'remove':\n\t\t\tcheckRef(baseAsAny[patch.name]);\n\t\t\tdelete baseAsAny[patch.name];\n\t\t\tbreak;\n\t\tcase 'list-set':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tcheckRef(base[patch.index]);\n\t\t\t\tbase[patch.index] = patch.value;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'list-push':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tbase.push(patch.value);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'list-delete':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tcheckRef(base[patch.index]);\n\t\t\t\tbase.splice(patch.index, patch.count);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'list-move-by-index':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tspliceResult = base.splice(patch.from, 1);\n\t\t\t\tbase.splice(patch.to, 0, spliceResult[0]);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'list-remove':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tdo {\n\t\t\t\t\tconst valueToRemove = patch.value;\n\t\t\t\t\tif (patch.only === 'last') {\n\t\t\t\t\t\tif (isRef(valueToRemove)) {\n\t\t\t\t\t\t\tindex = findLastIndex(\n\t\t\t\t\t\t\t\tbase,\n\t\t\t\t\t\t\t\t(item: any) => isRef(item) && compareRefs(item, valueToRemove),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tindex = base.lastIndexOf(valueToRemove);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (isRef(valueToRemove)) {\n\t\t\t\t\t\t\tindex = base.findIndex(\n\t\t\t\t\t\t\t\t(item: any) => isRef(item) && compareRefs(item, valueToRemove),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tindex = base.indexOf(valueToRemove);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (index !== -1) {\n\t\t\t\t\t\tcheckRef(base[index]);\n\t\t\t\t\t\tbase.splice(index, 1);\n\t\t\t\t\t}\n\t\t\t\t} while (!patch.only && index !== -1);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'list-add':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tconst alreadyHas = base.some((item: any) => {\n\t\t\t\t\tif (isObjectRef(item) && isObjectRef(patch.value)) {\n\t\t\t\t\t\treturn item.id === patch.value.id;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn item === patch.value;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (!alreadyHas) {\n\t\t\t\t\tbase.push(patch.value);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'list-move-by-ref':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tindex = base.findIndex((v) => compareRefs(v, patch.value));\n\t\t\t\tspliceResult = base.splice(index, 1);\n\t\t\t\tbase.splice(patch.index, 0, spliceResult[0]);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'list-insert':\n\t\t\tif (listCheck(base, patch)) {\n\t\t\t\tif (!patch.value && !patch.values) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Cannot apply list insert patch; expected value or values, received ${JSON.stringify(\n\t\t\t\t\t\t\tpatch,\n\t\t\t\t\t\t)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (patch.value) {\n\t\t\t\t\tbase.splice(patch.index, 0, patch.value);\n\t\t\t\t} else {\n\t\t\t\t\tbase.splice(patch.index, 0, ...patch.values!);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'delete':\n\t\t\t// collect all refs that are deleted\n\t\t\tif (Array.isArray(base)) {\n\t\t\t\tbase.forEach(checkRef);\n\t\t\t} else if (isObject(base)) {\n\t\t\t\tObject.values(base || {}).forEach(checkRef);\n\t\t\t}\n\t\t\treturn undefined;\n\t\tcase 'initialize':\n\t\t\treturn cloneDeep(patch.value);\n\t\tcase 'touch':\n\t\t\t// no-op\n\t\t\treturn base;\n\t\tdefault:\n\t\t\tthrow new Error(`Unsupported patch operation: ${(patch as any).op}`);\n\t}\n\treturn base;\n}\n\nexport function applyOperations<T extends NormalizedObject>(\n\tbase: T | undefined,\n\toperations: Operation[],\n\tdeletedRefs?: (ObjectRef | FileRef)[],\n\t/**\n\t * Provide and it will be assigned any authz info assigned\n\t * in applied operations\n\t */\n\tauthzRef?: { authz?: string },\n): T | undefined {\n\tlet cur = base as T | undefined;\n\tfor (const op of operations) {\n\t\tcur = applyPatch(cur, op.data, deletedRefs);\n\t\tif (authzRef && op.data.op === 'initialize' && op.authz) {\n\t\t\tauthzRef.authz = op.authz;\n\t\t}\n\t}\n\treturn cur;\n}\n\n/**\n * Mutates the original object in place. Returns all referenced\n * objects oids.\n */\nexport function substituteRefsWithObjects(\n\tbase: any,\n\trefs: Map<ObjectIdentifier, any>,\n\tused: ObjectIdentifier[] = [],\n): ObjectIdentifier[] {\n\tif (Array.isArray(base)) {\n\t\tfor (let i = 0; i < base.length; i++) {\n\t\t\tconst item = base[i];\n\t\t\tbase[i] = dereference(item, refs, used);\n\t\t\tif (isObject(base[i])) {\n\t\t\t\tsubstituteRefsWithObjects(base[i], refs, used);\n\t\t\t}\n\t\t}\n\t} else if (isFileRef(base)) {\n\t\t// don't do anything with file refs\n\t} else if (isObject(base)) {\n\t\t// not sure where to put this assertion but it's important to make\n\t\t// sure all nested objects include an OID\n\t\tassert(\n\t\t\tmaybeGetOid(base),\n\t\t\t`Object ${JSON.stringify(base)} must have an oid`,\n\t\t);\n\t\tfor (const key of Object.keys(base)) {\n\t\t\tbase[key] = dereference(base[key], refs, used);\n\n\t\t\t// now that objects are in place, recursively substitute\n\t\t\tif (isObject(base[key])) {\n\t\t\t\tsubstituteRefsWithObjects(base[key], refs, used);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn used;\n}\n\nfunction dereference(\n\tinput: any,\n\trefs: Map<ObjectIdentifier, any>,\n\tused: ObjectIdentifier[],\n): any {\n\tif (isObjectRef(input)) {\n\t\tused.push(input.id);\n\t\tconst resolved = refs.get(input.id);\n\t\tassert(!!resolved, `No value was found in object map for ${input.id}`);\n\t\treturn assignOid(resolved, input.id);\n\t} else {\n\t\treturn input;\n\t}\n}\n\nexport function substituteFirstLevelObjectsWithRefs<\n\tBase extends { [key: string]: any } | any[],\n>(\n\tbase: Base,\n\trefObjects: Map<ObjectIdentifier, any> = new Map(),\n): Map<ObjectIdentifier, any> {\n\tif (Array.isArray(base)) {\n\t\tfor (let i = 0; i < base.length; i++) {\n\t\t\tconst item = base[i];\n\t\t\t// special handling of file refs, which are treated like primitives\n\t\t\tif (isFileRef(item)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tassert(\n\t\t\t\t!isRef(item),\n\t\t\t\t'An object with refs was passed to substituteFirstLevelObjectsWithRefs, this is not allowed',\n\t\t\t);\n\t\t\tif (isObject(item)) {\n\t\t\t\tconst oid = getOid(item);\n\t\t\t\tbase[i] = {\n\t\t\t\t\t'@@type': 'ref',\n\t\t\t\t\tid: oid,\n\t\t\t\t};\n\t\t\t\trefObjects.set(oid, item);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor (const [key, value] of Object.entries(base)) {\n\t\t\t// special handling of file refs, which are treated like primitives\n\t\t\tif (isFileRef(value)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tassert(\n\t\t\t\t!isRef(value),\n\t\t\t\t'An object with refs was passed to substituteFirstLevelObjectsWithRefs, this is not allowed',\n\t\t\t);\n\t\t\tif (isObject(value)) {\n\t\t\t\tbase[key] = {\n\t\t\t\t\t'@@type': 'ref',\n\t\t\t\t\tid: getOid(value),\n\t\t\t\t};\n\n\t\t\t\trefObjects.set(getOid(value), value);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn refObjects;\n}\n\n/**\n * Takes a snapshot with applied OIDs and deconstructs it entirely\n * into individual objects with ref fields. Populates the supplied\n * map with the final objects.\n */\nexport function deconstructSnapshotToRefs(\n\tsnapshot: any,\n\trefTargets: Map<ObjectIdentifier, any>,\n) {\n\tif (typeof snapshot !== 'object') {\n\t\treturn;\n\t}\n\trefTargets.set(getOid(snapshot), snapshot);\n\tconst thisLevelOfTargets = substituteFirstLevelObjectsWithRefs(snapshot);\n\tfor (const [oid, obj] of thisLevelOfTargets.entries()) {\n\t\trefTargets.set(oid, obj);\n\t\tdeconstructSnapshotToRefs(obj, refTargets);\n\t}\n}\n\nexport function operationSupersedes(op: Operation): PropertyName | boolean {\n\t// todo: add 'remove'\n\tif (op.data.op === 'set') {\n\t\treturn op.data.name;\n\t}\n\n\treturn false;\n}\n\n/**\n * Determine if an operation is superseded by a set of supersession values\n * provided by operationSupersedes. Assumes the operation OID matches\n * already.\n */\nexport function isSuperseded(\n\top: Operation,\n\tsupersession: Set<PropertyName | boolean>,\n) {\n\tif (supersession.has(true)) {\n\t\treturn true;\n\t} else if (op.data.op === 'set' || op.data.op === 'remove') {\n\t\treturn supersession.has(op.data.name);\n\t}\n\n\treturn false;\n}\n\n/**\n * Allocates a copy with only valid keys for transmitting over\n * the protocol. TODO: make this unnecessary or evaluate if it's\n * worth it to do.\n */\nexport function pickValidOperationKeys(operation: Operation): Operation {\n\treturn {\n\t\toid: operation.oid,\n\t\ttimestamp: operation.timestamp,\n\t\tdata: operation.data,\n\t\tauthz: operation.authz,\n\t};\n}\n", "import { v4 } from 'uuid';\nimport { isFileRef } from './files.js';\nimport { isObjectRef, ObjectRef } from './operation.js';\nimport { isRef } from './refs.js';\nimport { assert, isObject, safeStringify } from './utils.js';\n\n/**\n * OIDs\n *\n * OIDs are used to identify objects in the document. They also encode\n * information about the object useful to identifying an object found\n * on its own and associating it back to its parent.\n *\n * An OID is structured as such:\n * <collection>/<root id>:<random>\n *\n * OIDs have a few characteristics:\n * - They include the collection name of the parent document\n * - They include the primary key of the parent document\n * - They may include a random sequence to identify sub-objects\n *\n * Collection name and document key are used to link any isolated\n * object back to its parent document.\n *\n * The random sequence allows the application to encode different\n * identities for objects at the same position in a document for\n * conflict resolution purposes\n */\n\nexport type ObjectIdentifier = string;\n\nconst SEGMENT_SEPARATOR = '/';\nconst RANDOM_SEPARATOR = ':';\n\n/**\n * This is the global, in-memory storage for all OIDs. It is used to\n * associate JS objects with OIDs without modifying the objects themselves.\n */\nconst oidMap = new WeakMap<any, ObjectIdentifier>();\n\nexport function getOid(obj: any) {\n\tconst oid = maybeGetOid(obj);\n\tassert(\n\t\t!!oid,\n\t\t`Object ${safeStringify(obj)} does not have an OID assigned to it`,\n\t);\n\treturn oid;\n}\n\nexport function maybeGetOid(obj: any): ObjectIdentifier | undefined {\n\tif (!isObject(obj)) {\n\t\treturn undefined;\n\t}\n\treturn oidMap.get(obj);\n}\n\nexport function assignOid(obj: any, oid: ObjectIdentifier) {\n\tassert(\n\t\tisObject(obj),\n\t\t`Only objects can be assigned OIDs, received ${safeStringify(obj)}`,\n\t);\n\tif (hasOid(obj)) {\n\t\tremoveOid(obj);\n\t}\n\toidMap.set(obj, oid);\n\treturn obj;\n}\n\nexport function hasOid(obj: any) {\n\treturn !!maybeGetOid(obj);\n}\n\nexport function removeOid(obj: any) {\n\toidMap.delete(obj);\n\treturn obj;\n}\n\n/**\n * For sub-objects, assign a random sub-OID if no OID\n * is already assigned.\n */\nexport function ensureOid(\n\tobj: any,\n\trootOid: ObjectIdentifier,\n\tcreateSubId?: () => string,\n) {\n\tif (!hasOid(obj)) {\n\t\tconst oid = createSubOid(rootOid, createSubId);\n\t\tassignOid(obj, oid);\n\t\treturn oid;\n\t} else {\n\t\treturn getOid(obj);\n\t}\n}\n\nexport function ensureCompatibleOid(\n\tobj: any,\n\trootOid: ObjectIdentifier,\n\tcreateSubId?: () => string,\n) {\n\tif (!hasOid(obj)) {\n\t\tconst oid = createSubOid(rootOid, createSubId);\n\t\tassignOid(obj, oid);\n\t\treturn oid;\n\t} else {\n\t\tconst existingOid = getOid(obj);\n\t\tif (!areOidsRelated(existingOid, rootOid)) {\n\t\t\tconst oid = createSubOid(rootOid, createSubId);\n\t\t\tassignOid(obj, oid);\n\t\t\treturn oid;\n\t\t} else {\n\t\t\treturn getOid(obj);\n\t\t}\n\t}\n}\n\nconst SANITIZE_PLACEHOLDERS = {\n\t'.': '˙',\n\t'/': '&slash;',\n\t':': ':',\n};\nfunction sanitizeFragment(id: string) {\n\t// replaces separator characters with placeholders\n\treturn id\n\t\t.replace(/[/]/g, SANITIZE_PLACEHOLDERS['/'])\n\t\t.replace(/[:]/g, SANITIZE_PLACEHOLDERS[':'])\n\t\t.replace(/[.]/g, SANITIZE_PLACEHOLDERS['.']);\n}\nfunction unsanitizeFragment(id: string) {\n\t// replaces placeholders with separator characters\n\treturn id\n\t\t.replace(/&slash;/g, '/')\n\t\t.replace(/:/g, ':')\n\t\t.replace(/˙/g, '.');\n}\n\n/**\n * Creates an OID for the document with a particular ID.\n * To create a sub-object OID, use createSubOid and pass\n * the root OID.\n */\nexport function createOid(\n\tcollection: string,\n\tdocumentId: string,\n\tsubId?: string,\n) {\n\tlet oid =\n\t\tsanitizeFragment(collection) +\n\t\tSEGMENT_SEPARATOR +\n\t\tsanitizeFragment(documentId);\n\tif (subId) {\n\t\toid += RANDOM_SEPARATOR + subId;\n\t}\n\treturn oid;\n}\n\nexport function createSubOid(\n\troot: ObjectIdentifier,\n\tcreateSubId: () => string = createOidSubId,\n) {\n\tconst { collection, id } = decomposeOid(root);\n\treturn createOid(collection, id, createSubId());\n}\n\nexport function decomposeOid(oid: ObjectIdentifier): {\n\tcollection: string;\n\tid: string;\n\tsubId?: string;\n} {\n\tlet [collection, coreId, ...others] = oid.split('/');\n\t// if 'others' exists, something's off, but maybe we can recover...\n\t// by assuming the last segment is the authz and bolting the rest onto coreId\n\tif (others.length) {\n\t\tconsole.error(\n\t\t\t`OID ${oid} has more than 3 segments. Attempting to parse it anyway.`,\n\t\t);\n\t\tcoreId += '/' + others.join('/');\n\t}\n\n\tconst [idOrLegacyPathId, random] = coreId.split(RANDOM_SEPARATOR);\n\n\tlet id;\n\t// legacy path handling. shouldn't be necessary anymore.\n\tif (idOrLegacyPathId.includes('.')) {\n\t\tid = idOrLegacyPathId.slice(0, idOrLegacyPathId.indexOf('.'));\n\t} else {\n\t\tid = idOrLegacyPathId;\n\t}\n\n\treturn {\n\t\tcollection: unsanitizeFragment(collection),\n\t\tid: unsanitizeFragment(id),\n\t\tsubId: random,\n\t};\n}\n\nexport function assertAllLevelsHaveOids(obj: any, root?: any) {\n\tassert(\n\t\tgetOid(obj),\n\t\t`Object ${safeStringify(obj)} must have an oid (child of ${safeStringify(\n\t\t\troot,\n\t\t)})`,\n\t);\n\tif (Array.isArray(obj)) {\n\t\tfor (const item of obj) {\n\t\t\tassertAllLevelsHaveOids(item, root || obj);\n\t\t}\n\t} else if (isObject(obj)) {\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tassertAllLevelsHaveOids(obj[key], root || obj);\n\t\t}\n\t}\n}\n\nexport function assignOidsToAllSubObjects(\n\tobj: any,\n\tcreateSubId?: () => string,\n) {\n\tconst rootOid = getOid(obj);\n\tif (Array.isArray(obj)) {\n\t\tlet item;\n\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\titem = obj[i];\n\t\t\tif (isObject(item) && !isRef(item)) {\n\t\t\t\tensureCompatibleOid(item, rootOid, createSubId);\n\t\t\t\tassignOidsToAllSubObjects(item, createSubId);\n\t\t\t}\n\t\t}\n\t} else if (isObject(obj) && !isRef(obj)) {\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tif (isObject(obj[key]) && !isRef(obj[key])) {\n\t\t\t\tensureCompatibleOid(obj[key], rootOid, createSubId);\n\t\t\t\tassignOidsToAllSubObjects(obj[key], createSubId);\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport function removeOidsFromAllSubObjects(obj: any) {\n\tremoveOid(obj);\n\n\tif (Array.isArray(obj)) {\n\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\tremoveOidsFromAllSubObjects(obj[i]);\n\t\t}\n\t} else if (isObject(obj)) {\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tremoveOidsFromAllSubObjects(obj[key]);\n\t\t}\n\t}\n}\n\nexport function createOidSubId() {\n\treturn v4().slice(0, 8);\n}\n\nexport function createRef(oid: ObjectIdentifier): ObjectRef {\n\treturn {\n\t\t'@@type': 'ref',\n\t\tid: oid,\n\t};\n}\n\nexport function normalize(\n\tobj: any,\n\trefs: Map<ObjectIdentifier, any> = new Map(),\n): Map<ObjectIdentifier, any> {\n\tif (Array.isArray(obj)) {\n\t\tconst oid = getOid(obj);\n\t\tconst copy = assignOid([], oid);\n\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\tconst value = obj[i];\n\t\t\tif (isObject(value)) {\n\t\t\t\tif (isObjectRef(value)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'An attempt was made to normalize an already normalized object! This is an error in verdant itself.',\n\t\t\t\t\t);\n\t\t\t\t} else if (isFileRef(value)) {\n\t\t\t\t\tcopy[i] = value;\n\t\t\t\t\tcontinue;\n\t\t\t\t} else {\n\t\t\t\t\tconst itemOid = getOid(value);\n\t\t\t\t\tcopy[i] = createRef(itemOid);\n\t\t\t\t\tnormalize(value, refs);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcopy[i] = value;\n\t\t\t}\n\t\t}\n\t\trefs.set(oid, copy);\n\t} else if (isObject(obj) && !isRef(obj)) {\n\t\tconst oid = getOid(obj);\n\t\tconst copy = assignOid({} as Record<string, any>, oid);\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tconst value = obj[key];\n\t\t\tif (isObject(value)) {\n\t\t\t\tif (isObjectRef(value)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'An attempt was made to normalize an already normalized object! This is an error in verdant itself.',\n\t\t\t\t\t);\n\t\t\t\t} else if (isFileRef(value)) {\n\t\t\t\t\t// stop here\n\t\t\t\t\tcopy[key] = value;\n\t\t\t\t} else {\n\t\t\t\t\tconst itemOid = getOid(value);\n\t\t\t\t\tcopy[key] = createRef(itemOid);\n\t\t\t\t\tnormalize(value, refs);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcopy[key] = value;\n\t\t\t}\n\t\t}\n\t\trefs.set(oid, copy);\n\t} else if (isRef(obj)) {\n\t}\n\treturn refs;\n}\n\n/**\n * Only normalizes direct children. The created map\n * of objects will still have nested objects.\n */\nexport function normalizeFirstLevel(obj: any) {\n\tconst refs = new Map<ObjectIdentifier, any>();\n\tconst oidKeyPairs = new Map<ObjectIdentifier, string | number>();\n\tif (Array.isArray(obj)) {\n\t\tconst oid = getOid(obj);\n\t\tconst copy = assignOid([], oid);\n\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\tconst value = obj[i];\n\t\t\tif (isObject(value)) {\n\t\t\t\tconst itemOid = getOid(value);\n\t\t\t\tcopy[i] = createRef(itemOid);\n\t\t\t\trefs.set(itemOid, value);\n\t\t\t\toidKeyPairs.set(itemOid, i);\n\t\t\t} else {\n\t\t\t\tcopy[i] = value;\n\t\t\t}\n\t\t}\n\t\trefs.set(oid, copy);\n\t} else if (isObject(obj)) {\n\t\tconst oid = getOid(obj);\n\t\tconst copy = assignOid({} as Record<string, any>, oid);\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tconst value = obj[key];\n\t\t\tif (isObject(value)) {\n\t\t\t\tconst itemOid = getOid(value);\n\t\t\t\tcopy[key] = createRef(itemOid);\n\t\t\t\trefs.set(itemOid, value);\n\t\t\t\toidKeyPairs.set(itemOid, key);\n\t\t\t} else {\n\t\t\t\tcopy[key] = value;\n\t\t\t}\n\t\t}\n\t\trefs.set(oid, copy);\n\t}\n\treturn { refs, oidKeyPairs };\n}\n\nexport function getOidRoot(oid: ObjectIdentifier) {\n\treturn oid.split('.')[0].split(RANDOM_SEPARATOR)[0];\n}\n\n/**\n * Returns an inclusive range of OIDs that represent\n * all of an OID's possible sub-objects.\n */\nexport function getOidSubIdRange(oid: ObjectIdentifier) {\n\tconst root = getOidRoot(oid);\n\tconst lastSubId = createSubOid(root, () => '\\uffff');\n\treturn [`${root}${RANDOM_SEPARATOR}`, lastSubId];\n}\n\nexport function getRoots(oids: ObjectIdentifier[]) {\n\tconst set = new Set<ObjectIdentifier>();\n\tfor (const oid of oids) {\n\t\tset.add(getOidRoot(oid));\n\t}\n\treturn Array.from(set);\n}\n\nexport function areOidsRelated(oidA: ObjectIdentifier, oidB: ObjectIdentifier) {\n\treturn getOidRoot(oidA) === getOidRoot(oidB);\n}\n\nexport function isRootOid(oid: ObjectIdentifier) {\n\treturn !oid.includes(RANDOM_SEPARATOR);\n}\n\n/**\n * Recursively rewrites any OIDs in an object which are 'foreign' -\n * i.e. relate to some other object/entity - to be local to the\n * current object. This is deterministic, so it can be done\n * on multiple clients independently with predictable results.\n */\nexport function fixForeignOids(obj: any) {\n\tconst oid = maybeGetOid(obj);\n\tif (!oid) return;\n\n\tif (Array.isArray(obj)) {\n\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\tmigrateForeignOid(oid, obj[i]);\n\t\t\tfixForeignOids(obj[i]);\n\t\t}\n\t} else if (isObject(obj)) {\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tmigrateForeignOid(oid, obj[key]);\n\t\t\tfixForeignOids(obj[key]);\n\t\t}\n\t}\n}\n\nfunction migrateForeignOid(parentOid: ObjectIdentifier, child: any) {\n\tconst childOid = maybeGetOid(child);\n\tif (childOid && !areOidsRelated(parentOid, childOid)) {\n\t\tconst { subId, id } = decomposeOid(childOid);\n\t\t// reuse existing subId. if child is a foreign root, use its id as subId\n\t\tassignOid(\n\t\t\tchild,\n\t\t\tcreateSubOid(parentOid, () => subId || id),\n\t\t);\n\t}\n}\n\n/**\n * Returns a list of all OIDs assigned to this object\n * and all sub-objects.\n */\nexport function getAllOids(root: any) {\n\tconst oids = new Set<ObjectIdentifier>();\n\tconst stack = [root];\n\twhile (stack.length) {\n\t\tconst obj = stack.pop();\n\t\tconst oid = maybeGetOid(obj);\n\t\tif (oid) {\n\t\t\toids.add(oid);\n\t\t}\n\t\tif (Array.isArray(obj)) {\n\t\t\tstack.push(...obj);\n\t\t} else if (isObject(obj)) {\n\t\t\tstack.push(...Object.values(obj));\n\t\t}\n\t}\n\treturn Array.from(oids);\n}\n", "import {\n\tassignOid,\n\tcreateOid,\n\tdecomposeOid,\n\tgetOidRoot,\n\tObjectIdentifier,\n} from './oids.js';\nimport { isObject } from './utils.js';\n\nexport const LEGACY_OID_KEY = '__@@oid_do_not_use';\nexport const OID_KEY = '@@id';\n\nexport function maybeGetOidProperty(obj: any) {\n\tif (!isObject(obj)) {\n\t\treturn undefined;\n\t}\n\treturn obj[OID_KEY] || obj[LEGACY_OID_KEY];\n}\n\nfunction removeOidProperty(obj: any) {\n\tif (!isObject(obj)) {\n\t\treturn obj;\n\t}\n\tdelete obj[LEGACY_OID_KEY];\n\tdelete obj[OID_KEY];\n\treturn obj;\n}\n\nfunction copyOidFromPropertyToSystem(obj: any) {\n\tconst oid = maybeGetOidProperty(obj);\n\tif (oid) {\n\t\tassignOid(obj, oid);\n\t}\n}\n\n/**\n *\n * Removes the special property from all objects in the given object\n * which have an OID, transferring the OID from the property to the OID\n * system in-memory.\n */\nexport function removeOidPropertiesFromAllSubObjects(obj: any) {\n\tcopyOidFromPropertyToSystem(obj);\n\tremoveOidProperty(obj);\n\n\tif (Array.isArray(obj)) {\n\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\tremoveOidPropertiesFromAllSubObjects(obj[i]);\n\t\t}\n\t} else if (isObject(obj)) {\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tremoveOidPropertiesFromAllSubObjects(obj[key]);\n\t\t}\n\t}\n}\n\nexport function isLegacyDotOid(oid: ObjectIdentifier) {\n\tconst partBeforeRandomSep = oid.split(':')[0];\n\treturn partBeforeRandomSep.includes('.');\n}\n\nexport function convertLegacyOid(oid: ObjectIdentifier) {\n\tconst { collection, id, subId } = decomposeOid(oid);\n\treturn createOid(collection, id, subId);\n}\n\n// NOTE: all legacy OIDs should now be gone.\nexport const MATCH_LEGACY_OID_JSON_STRING = /\"\\w+\\/[^\"]+?(\\.[^\"]+)+\\:[\\S]+?\"/g;\nexport function replaceLegacyOidsInJsonString(string: string) {\n\t// replace every match of a legacy OID, converting to a new OID\n\treturn string.replaceAll(MATCH_LEGACY_OID_JSON_STRING, (match) => {\n\t\tconst legacyOid = match.slice(1, match.length - 1);\n\t\treturn `\"${convertLegacyOid(legacyOid)}\"`;\n\t});\n}\nexport function replaceLegacyOidsInObject(obj: any) {\n\treturn JSON.parse(replaceLegacyOidsInJsonString(JSON.stringify(obj)));\n}\n\nexport function getLegacyDotOidSubIdRange(oid: ObjectIdentifier) {\n\tconst root = getOidRoot(oid);\n\treturn [`${root}.`, `${root}.\\uffff`];\n}\n\nexport function isOidKey(key: string) {\n\treturn key === OID_KEY || key === LEGACY_OID_KEY;\n}\n", "/**\n * High-level patch creation for use with complex nested objects.\n */\n\nimport { AuthorizationKey } from './authz.js';\nimport { diffToPatches } from './diffing.js';\nimport { FileRef } from './files.js';\nimport { createRef, createSubOid, ObjectIdentifier } from './oids.js';\nimport {\n\tinitialToPatches,\n\tObjectRef,\n\tOperation,\n\tPropertyName,\n\tPropertyValue,\n\tshallowInitialToPatches,\n} from './operation.js';\nimport { isRef } from './refs.js';\nimport { assert, isObject } from './utils.js';\n\nexport class PatchCreator {\n\tconstructor(\n\t\treadonly getNow: () => string,\n\t\treadonly createSubId?: () => string,\n\t) {}\n\n\tisPrimitive = (value: any) => {\n\t\treturn !isObject(value) || isRef(value);\n\t};\n\n\tcreateDiff = (\n\t\tfrom: any,\n\t\tto: any,\n\t\toptions: {\n\t\t\tmergeUnknownObjects?: boolean;\n\t\t\t/** @deprecated use the equivalent 'merge' */\n\t\t\tdefaultUndefined?: boolean;\n\t\t\tmerge?: boolean;\n\t\t\tauthz?: AuthorizationKey;\n\t\t} = {},\n\t) => {\n\t\treturn diffToPatches(from, to, this.getNow, this.createSubId, [], options);\n\t};\n\n\tcreateInitialize = (\n\t\tobj: any,\n\t\toid: ObjectIdentifier,\n\t\tauthz?: AuthorizationKey,\n\t\tshallow?: boolean,\n\t) => {\n\t\tif (shallow) {\n\t\t\treturn shallowInitialToPatches(\n\t\t\t\tobj,\n\t\t\t\toid,\n\t\t\t\tthis.getNow,\n\t\t\t\tundefined,\n\t\t\t\tauthz ? { authz } : undefined,\n\t\t\t);\n\t\t}\n\t\treturn initialToPatches(\n\t\t\tobj,\n\t\t\toid,\n\t\t\tthis.getNow,\n\t\t\tthis.createSubId,\n\t\t\tundefined,\n\t\t\tauthz ? { authz } : undefined,\n\t\t);\n\t};\n\n\tcreateSet = (\n\t\toid: ObjectIdentifier,\n\t\tkey: PropertyName,\n\t\tvalue: any,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\t// incoming value must be normalized. if it's not a primitive, it and all sub-objects\n\t\t// must be created\n\t\tif (this.isPrimitive(value)) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'set',\n\t\t\t\t\t\tname: key,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t} else {\n\t\t\tconst itemOid = createSubOid(oid, this.createSubId);\n\t\t\treturn [\n\t\t\t\t// since we're setting a complex nested object, we can initialize it wholesale.\n\t\t\t\t// no diffing to do.\n\t\t\t\t...initialToPatches(\n\t\t\t\t\tvalue,\n\t\t\t\t\titemOid,\n\t\t\t\t\tthis.getNow,\n\t\t\t\t\tthis.createSubId,\n\t\t\t\t\tundefined,\n\t\t\t\t\t{\n\t\t\t\t\t\tauthz,\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\t// then set the reference to the object\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'set',\n\t\t\t\t\t\tvalue: createRef(itemOid),\n\t\t\t\t\t\tname: key,\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t};\n\n\tcreateRemove = (\n\t\toid: ObjectIdentifier,\n\t\tkey: PropertyName,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\treturn [\n\t\t\t{\n\t\t\t\toid,\n\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\tdata: {\n\t\t\t\t\top: 'remove',\n\t\t\t\t\tname: key,\n\t\t\t\t},\n\t\t\t\tauthz,\n\t\t\t},\n\t\t];\n\t};\n\n\tcreateListSet = (\n\t\toid: ObjectIdentifier,\n\t\tindex: number,\n\t\tvalue: any,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tassert(index >= 0, 'List index must be non-negative');\n\t\tif (this.isPrimitive(value)) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-set',\n\t\t\t\t\t\tindex,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t} else {\n\t\t\tconst itemOid = createSubOid(oid, this.createSubId);\n\t\t\treturn [\n\t\t\t\t...initialToPatches(\n\t\t\t\t\tvalue,\n\t\t\t\t\titemOid,\n\t\t\t\t\tthis.getNow,\n\t\t\t\t\tthis.createSubId,\n\t\t\t\t\tundefined,\n\t\t\t\t\t{\n\t\t\t\t\t\tauthz,\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-set',\n\t\t\t\t\t\tindex,\n\t\t\t\t\t\tvalue: createRef(itemOid),\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t};\n\n\tcreateListPush = (\n\t\toid: ObjectIdentifier,\n\t\tvalue: any,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tif (this.isPrimitive(value)) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-push',\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t} else {\n\t\t\tconst itemOid = createSubOid(oid, this.createSubId);\n\t\t\treturn [\n\t\t\t\t...initialToPatches(value, itemOid, this.getNow, undefined, undefined, {\n\t\t\t\t\tauthz,\n\t\t\t\t}),\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-push',\n\t\t\t\t\t\tvalue: createRef(itemOid),\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t};\n\n\tcreateListAdd = (\n\t\toid: ObjectIdentifier,\n\t\tvalue: any,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tif (!this.isPrimitive(value)) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-add',\n\t\t\t\t\t\tvalue: createRef(value),\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t} else {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-add',\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t};\n\n\tcreateListInsert = (\n\t\toid: ObjectIdentifier,\n\t\tindex: number,\n\t\tvalue: any,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tassert(index >= 0, 'List index must be non-negative');\n\t\tif (this.isPrimitive(value)) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-insert',\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\tindex,\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t} else {\n\t\t\tconst itemOid = createSubOid(oid, this.createSubId);\n\t\t\treturn [\n\t\t\t\t...initialToPatches(\n\t\t\t\t\tvalue,\n\t\t\t\t\titemOid,\n\t\t\t\t\tthis.getNow,\n\t\t\t\t\tthis.createSubId,\n\t\t\t\t\tundefined,\n\t\t\t\t\tauthz\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tauthz,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: undefined,\n\t\t\t\t),\n\t\t\t\t{\n\t\t\t\t\toid,\n\t\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\top: 'list-insert',\n\t\t\t\t\t\tvalue: createRef(itemOid),\n\t\t\t\t\t\tindex,\n\t\t\t\t\t},\n\t\t\t\t\tauthz,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t};\n\n\tcreateListInsertMany = (\n\t\toid: ObjectIdentifier,\n\t\tindex: number,\n\t\tvalues: any[],\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tassert(index >= 0, 'List index must be non-negative');\n\t\tconst operations: Operation[] = [];\n\t\tconst refs = values.map((value) => {\n\t\t\tif (this.isPrimitive(value)) return value;\n\t\t\tconst subOid = createSubOid(oid, this.createSubId);\n\t\t\toperations.push(\n\t\t\t\t...initialToPatches(\n\t\t\t\t\tvalue,\n\t\t\t\t\tsubOid,\n\t\t\t\t\tthis.getNow,\n\t\t\t\t\tthis.createSubId,\n\t\t\t\t\tundefined,\n\t\t\t\t\t{\n\t\t\t\t\t\tauthz,\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn createRef(subOid);\n\t\t});\n\t\toperations.push({\n\t\t\toid,\n\t\t\ttimestamp: this.getNow(),\n\t\t\tdata: {\n\t\t\t\top: 'list-insert',\n\t\t\t\tvalues: refs,\n\t\t\t\tindex,\n\t\t\t},\n\t\t\tauthz,\n\t\t});\n\t\treturn operations;\n\t};\n\n\tcreateListRemove = (\n\t\toid: ObjectIdentifier,\n\t\tvalue: PropertyValue,\n\t\tonly?: 'first' | 'last',\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\treturn [\n\t\t\t{\n\t\t\t\toid,\n\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\tdata: {\n\t\t\t\t\top: 'list-remove',\n\t\t\t\t\tvalue,\n\t\t\t\t\tonly,\n\t\t\t\t},\n\t\t\t\tauthz,\n\t\t\t},\n\t\t];\n\t};\n\n\tcreateListDelete = (\n\t\toid: ObjectIdentifier,\n\t\tindex: number,\n\t\tcount: number = 1,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tassert(index >= 0, 'List index must be non-negative');\n\t\tassert(count > 0, 'Count must be positive and non-zero');\n\t\treturn [\n\t\t\t{\n\t\t\t\toid,\n\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\tdata: {\n\t\t\t\t\top: 'list-delete',\n\t\t\t\t\tindex,\n\t\t\t\t\tcount,\n\t\t\t\t},\n\t\t\t\tauthz,\n\t\t\t},\n\t\t];\n\t};\n\n\tcreateListMoveByRef = (\n\t\toid: ObjectIdentifier,\n\t\tvalue: ObjectRef | FileRef,\n\t\tindex: number,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tassert(index >= 0, 'List index must be non-negative');\n\t\treturn [\n\t\t\t{\n\t\t\t\toid,\n\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\tdata: {\n\t\t\t\t\top: 'list-move-by-ref',\n\t\t\t\t\tvalue,\n\t\t\t\t\tindex,\n\t\t\t\t},\n\t\t\t\tauthz,\n\t\t\t},\n\t\t];\n\t};\n\n\tcreateListMoveByIndex = (\n\t\toid: ObjectIdentifier,\n\t\tfromIndex: number,\n\t\ttoIndex: number,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\tassert(fromIndex >= 0, 'List move from index must be non-negative');\n\t\tassert(toIndex >= 0, 'List move to index must be non-negative');\n\t\treturn [\n\t\t\t{\n\t\t\t\toid,\n\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\tdata: {\n\t\t\t\t\top: 'list-move-by-index',\n\t\t\t\t\tfrom: fromIndex,\n\t\t\t\t\tto: toIndex,\n\t\t\t\t},\n\t\t\t\tauthz,\n\t\t\t},\n\t\t];\n\t};\n\n\tcreateDelete = (\n\t\toid: ObjectIdentifier,\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\treturn [\n\t\t\t{\n\t\t\t\toid,\n\t\t\t\ttimestamp: this.getNow(),\n\t\t\t\tdata: {\n\t\t\t\t\top: 'delete',\n\t\t\t\t},\n\t\t\t\tauthz,\n\t\t\t},\n\t\t];\n\t};\n\n\tcreateDeleteAll = (\n\t\toids: ObjectIdentifier[],\n\t\tauthz?: AuthorizationKey,\n\t): Operation[] => {\n\t\treturn oids.map((oid) => ({\n\t\t\toid,\n\t\t\ttimestamp: this.getNow(),\n\t\t\tdata: {\n\t\t\t\top: 'delete',\n\t\t\t},\n\t\t\tauthz,\n\t\t}));\n\t};\n}\n", "import { AuthorizationKey } from './authz.js';\nimport { VerdantError } from './error.js';\nimport {\n\tareOidsRelated,\n\tassignOid,\n\tcreateRef,\n\tgetOid,\n\tmaybeGetOid,\n\tObjectIdentifier,\n} from './oids.js';\nimport { isOidKey } from './oidsLegacy.js';\nimport { Operation } from './operation.js';\nimport { PatchCreator } from './patch.js';\nimport { compareRefs, isRef } from './refs.js';\nimport { cloneDeep, isObject } from './utils.js';\n\nexport type DiffContext = {\n\tpatches: Operation[];\n\t/**\n\t * If an object is merged with another and the new one does not\n\t * have an OID assigned, assume it is the same identity as previous\n\t */\n\tmergeUnknownObjects?: boolean;\n\t/**\n\t * If an incoming value is not assigned on the new object, use the previous value.\n\t * If false, undefined properties will erase the previous value.\n\t */\n\tmerge?: boolean;\n\t/**\n\t * Authorization to apply to all created operations\n\t */\n\tauthz?: AuthorizationKey;\n\tpatchCreator: PatchCreator;\n};\n\n/**\n * Compares two anythings and determines if they\n * represent the same thing. Works for primitives,\n * refs, and objects with OIDs.\n */\nfunction areTheSameIdentity(a: any, b: any) {\n\tif (a === b) return true;\n\tif (isRef(a) && isRef(b)) return compareRefs(a, b);\n\tconst aOid = maybeGetOid(a);\n\tconst bOid = maybeGetOid(b);\n\tif (aOid && bOid && aOid === bOid) return true;\n\treturn false;\n}\n\n/**\n * Enforces OID rules on subobjects being added to an entity.\n * - Every sub-object must have an OID\n * - The sub-object's OID must relate to the parent OID\n */\nfunction enforceAssignedOid(\n\tparentOid: ObjectIdentifier,\n\tnewObject: any,\n\texistingObjectOid: ObjectIdentifier | undefined,\n\tctx: DiffContext,\n) {\n\tif (!isDiffableObject(newObject)) {\n\t\t// nothing to do, the new value cannot have an oid as it is not\n\t\t// a sub-object.\n\t\treturn newObject;\n\t}\n\n\tconst oid = maybeGetOid(newObject);\n\tif (!oid) {\n\t\t// if merge unknown objects is enabled, we can assume the new object is the same\n\t\t// as the existing object (if present) and use its oid. otherwise we assign a new one.\n\t\tif (ctx.mergeUnknownObjects && existingObjectOid) {\n\t\t\tassignOid(newObject, existingObjectOid);\n\t\t}\n\t\t// NOTE: new OID assignments are done in patchCreator.\n\t} else if (!areOidsRelated(parentOid, oid)) {\n\t\t// when there's any doubt, clone the whole object. false -> do not copy OIDs\n\t\tconst clone = cloneDeep(newObject, false);\n\t\t// NOTE: new OID assignments are done in patchCreator.\n\t\treturn clone;\n\t}\n\treturn newObject;\n}\n\nfunction isDiffableObject(val: any) {\n\treturn isObject(val) && !isRef(val);\n}\n\nexport function diffToPatches(\n\tfrom: any,\n\tto: any,\n\tgetNow: () => string,\n\tcreateSubId?: () => string,\n\t_?: any, // legacy, TODO: remove\n\toptions?: {\n\t\tmergeUnknownObjects?: boolean;\n\t\tmerge?: boolean;\n\t\t/** @deprecated - use 'merge' */\n\t\tdefaultUndefined?: boolean;\n\t\tauthz?: AuthorizationKey;\n\t},\n) {\n\tconst ctx: DiffContext = {\n\t\tpatches: [],\n\t\tmergeUnknownObjects: options?.mergeUnknownObjects,\n\t\tmerge: options?.merge ?? options?.defaultUndefined,\n\t\tauthz: options?.authz,\n\t\tpatchCreator: new PatchCreator(getNow, createSubId),\n\t};\n\tdiff(from, to, ctx);\n\treturn ctx.patches;\n}\n\nexport function diff(from: any, to: any, ctx: DiffContext) {\n\tif (Array.isArray(from) && Array.isArray(to)) {\n\t\tdiffLists(from, to, ctx);\n\t} else if (Array.isArray(from) || Array.isArray(to)) {\n\t\tthrow new VerdantError(\n\t\t\tVerdantError.Code.Unexpected,\n\t\t\tundefined,\n\t\t\t'Cannot diff between array and non-array',\n\t\t);\n\t} else if (isDiffableObject(from) && isDiffableObject(to)) {\n\t\tdiffObjects(from, to, ctx);\n\t}\n}\n\n/**\n * Deep diff lists of any kind of item. Adds patches for the changes\n * to the context patch list.\n * @param from - the original list snapshot. must be the full snapshot, no references.\n * @param to - the new list snapshot. must be the full snapshot, no references.\n * @param ctx - the diff context to add patches to.\n */\nexport function diffLists(from: any[], to: any[], ctx: DiffContext) {\n\t// from object must be registered with an OID.\n\tconst oid = getOid(from);\n\t// this copy will be mutated to align with inserts, making things easier to compare.\n\tconst fromCopy = [];\n\t// while iterating from, also collect some metadata.\n\tconst oidsInFrom = new Set();\n\tfor (let i = 0; i < from.length; i++) {\n\t\tconst value = from[i];\n\t\tfromCopy[i] = value;\n\t\tconst oid = maybeGetOid(value);\n\t\tif (oid) {\n\t\t\toidsInFrom.add(oid);\n\t\t}\n\t}\n\n\t// first, normalize incoming data according to OID rules. this is done early\n\t// so future equality checks are according to configuration like mergeUnknownObjects.\n\t// for example, if a bare (no oid) object is supplied for an item and mergeUnknownObjects\n\t// is set, this will assign it the same OID as the existing item at that index, so it will\n\t// pass equality checks for insertion range, etc.\n\tfor (let i = 0; i < to.length; i++) {\n\t\tconst value = to[i];\n\t\tconst oldValue = from[i];\n\t\tto[i] = enforceAssignedOid(oid, value, maybeGetOid(oldValue), ctx);\n\t}\n\n\t// track whether the new list has gaps in it. a gap\n\t// means we can no longer use list-push for new items.\n\tlet noGaps = true;\n\t// track any items we move by reference, so we remember to\n\t// not delete them later.\n\tconst movedItems = new Set<ObjectIdentifier>();\n\tconst overwrittenItems = new Set<ObjectIdentifier>();\n\tfor (let i = 0; i < to.length; i++) {\n\t\tconst value = to[i];\n\t\tconst oldValue = fromCopy[i];\n\t\tif (value === undefined) {\n\t\t\tnoGaps = false;\n\t\t}\n\t\tconst itemOid = maybeGetOid(value);\n\n\t\t// we decide if this item is being added to the end of the list if:\n\t\t// - there were no empty spaces before it in the new list\n\t\t// - the index is beyond the scope of the original list.\n\t\t// the second condition is carefully selected since it accounts for\n\t\t// the prior list having gaps, too. length should represent the final\n\t\t// defined item even if gaps were there previously. we don't want to\n\t\t// accidentally 'push' into a gap, which would put the item in the wrong place.\n\t\tconst isEndOfList = noGaps && i >= fromCopy.length;\n\n\t\t// this branch exclusively deals with object references.\n\t\tif (itemOid && oidsInFrom.has(itemOid)) {\n\t\t\t// this item was in the old list, so no matter what we want to\n\t\t\t// preserve its identity. the rest of the branches here all\n\t\t\t// assume the item is new and initialize it.\n\t\t\tif (areTheSameIdentity(value, oldValue)) {\n\t\t\t\t// the item hasn't moved. we just diff it in place.\n\t\t\t\tdiff(oldValue, value, ctx);\n\t\t\t} else {\n\t\t\t\t// the item has moved. we are currently visiting its new index,\n\t\t\t\t// so we can move it by reference now\n\t\t\t\tctx.patches.push(\n\t\t\t\t\t...ctx.patchCreator.createListMoveByRef(\n\t\t\t\t\t\toid,\n\t\t\t\t\t\tcreateRef(itemOid),\n\t\t\t\t\t\ti,\n\t\t\t\t\t\tctx.authz,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\t// the problem is, a move by ref is not the same as what\n\t\t\t\t// we really observed here, since it's more like an insertion\n\t\t\t\t// and not an overwrite. to complicate this, the replaced item\n\t\t\t\t// at this index might actually have moved, not been replaced.\n\t\t\t\t// we mark the item that was at this index previously, and if\n\t\t\t\t// we don't see it later, we'll delete it.\n\t\t\t\tconst fromOid = maybeGetOid(oldValue);\n\t\t\t\tif (fromOid) {\n\t\t\t\t\toverwrittenItems.add(fromOid);\n\t\t\t\t}\n\n\t\t\t\t// remember this item so we don't delete it later.\n\t\t\t\tmovedItems.add(itemOid);\n\t\t\t}\n\t\t} else if (isEndOfList) {\n\t\t\t// this will initialize all sub-objects in the item, too\n\t\t\tctx.patches.push(\n\t\t\t\t...ctx.patchCreator.createListPush(oid, value, ctx.authz),\n\t\t\t);\n\t\t} else if (areTheSameIdentity(value, oldValue)) {\n\t\t\t// note : since the branch above covers object references which\n\t\t\t// were present in the original list, logically this branch only\n\t\t\t// covers primitives. either way, call diff, it's just more\n\t\t\t// proper to do so.\n\t\t\tdiff(oldValue, value, ctx);\n\t\t} else {\n\t\t\t// the identity of this item has changed. we can now evaluate\n\t\t\t// whether we should replace the original item or insert a new\n\t\t\t// item.\n\n\t\t\t// we can insert an item if the items which used to be at this\n\t\t\t// index and the one before it are still in the list next to the\n\t\t\t// new item.\n\t\t\t// i.e. [0,1,2,3] -> [0,1,4,2,3] can insert 4 at index 2.\n\t\t\t// theoretically we could support inserting a group of items,\n\t\t\t// like [0,1,2,3] -> [0,1,4,5,6,2,3], but in practice this is much\n\t\t\t// harder to detect.\n\t\t\tconst isPreviousItemStillThere =\n\t\t\t\ti === 0 || areTheSameIdentity(to[i - 1], fromCopy[i - 1]);\n\t\t\tconst isNextItemStillThere =\n\t\t\t\ti === to.length - 1 ||\n\t\t\t\tareTheSameIdentity(\n\t\t\t\t\tto[i + 1],\n\t\t\t\t\t// only \"i\" here because in the prior list, this was the item\n\t\t\t\t\t// at the insertion point.\n\t\t\t\t\tfromCopy[i],\n\t\t\t\t);\n\t\t\tif (isPreviousItemStillThere && isNextItemStillThere) {\n\t\t\t\tctx.patches.push(\n\t\t\t\t\t...ctx.patchCreator.createListInsert(oid, i, value, ctx.authz),\n\t\t\t\t);\n\t\t\t\t// mutate from copy to mirror this insert so further comparisons\n\t\t\t\t// are correct. we just insert an undefined.\n\t\t\t\tfromCopy.splice(i, 0, undefined);\n\t\t\t} else {\n\t\t\t\t// if we can't insert, we have to replace the item.\n\t\t\t\tctx.patches.push(\n\t\t\t\t\t...ctx.patchCreator.createListSet(oid, i, value, ctx.authz),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t// remove any remaining items at the end of the array.\n\tconst deletedItemsAtEnd = fromCopy.length - to.length;\n\tif (deletedItemsAtEnd > 0) {\n\t\tfor (let i = fromCopy.length - 1; i >= to.length; i--) {\n\t\t\tconst value = fromCopy[i];\n\t\t\tconst itemOid = maybeGetOid(value);\n\t\t\tif (itemOid) {\n\t\t\t\t// avoid deleting moved objects that were at the end of the list before.\n\t\t\t\t// their reference was moved elsewhere, but their contents must be retained.\n\t\t\t\tif (!movedItems.has(itemOid)) {\n\t\t\t\t\t// if sub-items were objects, we need to delete them all\n\t\t\t\t\t// this should recursively delete children of these items\n\t\t\t\t\t// also!\n\t\t\t\t\tdeleteWithSubObjects(value, ctx);\n\t\t\t\t\tctx.patches.push(\n\t\t\t\t\t\t...ctx.patchCreator.createListRemove(\n\t\t\t\t\t\t\toid,\n\t\t\t\t\t\t\tcreateRef(itemOid),\n\t\t\t\t\t\t\t'last',\n\t\t\t\t\t\t\tctx.authz,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tctx.patches.push(\n\t\t\t\t\t...ctx.patchCreator.createListRemove(oid, value, 'last', ctx.authz),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const overwrittenOid of overwrittenItems) {\n\t\tif (movedItems.has(overwrittenOid)) {\n\t\t\t// this item was moved, not overwritten. we don't want to delete it.\n\t\t\tcontinue;\n\t\t}\n\t\t// this item was overwritten, not moved. we need to delete it.\n\t\t// if sub-items were objects, we need to delete them all\n\t\t// this should recursively delete children of these items\n\t\t// also!\n\t\tconst item = from.find((x) => maybeGetOid(x) === overwrittenOid);\n\t\tif (item) {\n\t\t\tdeleteWithSubObjects(item, ctx);\n\t\t}\n\t\tctx.patches.push(\n\t\t\t...ctx.patchCreator.createListRemove(\n\t\t\t\toid,\n\t\t\t\tcreateRef(overwrittenOid),\n\t\t\t\t'last',\n\t\t\t\tctx.authz,\n\t\t\t),\n\t\t);\n\t}\n}\n\nexport function diffObjects(from: any, to: any, ctx: DiffContext) {\n\tconst oldKeys = new Set(Object.keys(from));\n\tconst oid = getOid(from);\n\tfor (const key in to) {\n\t\tconst value = to[key];\n\t\tif (value === undefined && ctx.merge) continue;\n\t\toldKeys.delete(key);\n\t\tif (isOidKey(key)) continue; // legacy\n\t\tconst oldValue = from[key];\n\t\tif (!isDiffableObject(value)) {\n\t\t\tif (!areTheSameIdentity(value, oldValue)) {\n\t\t\t\t// the value has changed for this key\n\t\t\t\t// if the value is undefined (merge is off), delete instead of\n\t\t\t\t// set.\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\tctx.patches.push(\n\t\t\t\t\t\t...ctx.patchCreator.createRemove(oid, key, ctx.authz),\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tctx.patches.push(\n\t\t\t\t\t\t...ctx.patchCreator.createSet(oid, key, value, ctx.authz),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// if there was an old value at this key, delete it.\n\t\t\t\tdeleteWithSubObjects(oldValue, ctx);\n\t\t\t} else {\n\t\t\t\t// two primitive, non-diffable values of the\n\t\t\t\t// same identity are considered equal.\n\t\t\t\t// we have nothing to do here.\n\t\t\t}\n\t\t} else {\n\t\t\t// make sure incoming object has a valid OID assigned,\n\t\t\t// and/or copy the existing value's OID if mergeUnknownObjects is\n\t\t\t// true.\n\t\t\tenforceAssignedOid(oid, value, maybeGetOid(oldValue), ctx);\n\t\t\tif (!oldValue) {\n\t\t\t\t// set the new value on this key\n\t\t\t\tctx.patches.push(\n\t\t\t\t\t...ctx.patchCreator.createSet(oid, key, value, ctx.authz),\n\t\t\t\t);\n\t\t\t} else if (!areTheSameIdentity(value, oldValue)) {\n\t\t\t\t// overwrite the key with the changed value\n\t\t\t\tctx.patches.push(\n\t\t\t\t\t...ctx.patchCreator.createSet(oid, key, value, ctx.authz),\n\t\t\t\t);\n\t\t\t\t// and we must also fully delete the\n\t\t\t\t// old object and its children\n\t\t\t\tdeleteWithSubObjects(oldValue, ctx);\n\t\t\t} else {\n\t\t\t\t// finally, this is the case when the identity of\n\t\t\t\t// the new and old values are the same -- we still\n\t\t\t\t// have to diff the contents.\n\t\t\t\tdiff(oldValue, value, ctx);\n\t\t\t}\n\t\t}\n\t}\n\t// this set now only contains keys which were not in the new object\n\tif (!ctx.merge) {\n\t\tfor (const key of oldKeys) {\n\t\t\tif (isOidKey(key)) continue;\n\t\t\t// remove the key entirely\n\t\t\tctx.patches.push(...ctx.patchCreator.createRemove(oid, key, ctx.authz));\n\t\t\t// push the deletes for the contents of the item\n\t\t\tdeleteWithSubObjects(from[key], ctx);\n\t\t}\n\t}\n}\n\nexport function deleteWithSubObjects(root: any, ctx: DiffContext) {\n\tif (!isDiffableObject(root)) {\n\t\treturn;\n\t}\n\tconst oid = maybeGetOid(root);\n\tif (oid) {\n\t\tctx.patches.push(...ctx.patchCreator.createDelete(oid, ctx.authz));\n\t\tfor (const key in root) {\n\t\t\tconst value = root[key];\n\t\t\tdeleteWithSubObjects(value, ctx);\n\t\t}\n\t}\n}\n", "import { generateId } from './utils.js';\n\nexport class EventSubscriber<\n\tEvents extends { [key: string]: (...args: any[]) => void },\n> {\n\tprotected subscribers: Record<\n\t\tstring,\n\t\tRecord<string, (...args: any[]) => void>\n\t> = {} as any;\n\tprotected counts: Record<string, number> = {} as any;\n\tprivate _disabled = false;\n\tprotected disposed = false;\n\n\tconstructor(private _onAllUnsubscribed?: (event: keyof Events) => void) {}\n\n\tget disabled() {\n\t\treturn this._disabled;\n\t}\n\n\tsubscriberCount = (event: Extract<keyof Events, string>) => {\n\t\treturn this.counts[event] ?? 0;\n\t};\n\n\ttotalSubscriberCount = () => {\n\t\treturn Object.values(this.counts).reduce((acc, count) => acc + count, 0);\n\t};\n\n\tsubscribe = <K extends Extract<keyof Events, string>>(\n\t\tevent: K,\n\t\tcallback: Events[K],\n\t) => {\n\t\tconst key = generateId();\n\t\tlet subscribers = this.subscribers[event];\n\t\tif (!subscribers) {\n\t\t\tsubscribers = this.subscribers[event] = {};\n\t\t}\n\t\tsubscribers[key] = callback;\n\t\tthis.counts[event] = (this.counts[event] || 0) + 1;\n\t\treturn () => {\n\t\t\t// already removed\n\t\t\tif (!this.subscribers[event]) return;\n\n\t\t\tdelete this.subscribers[event][key];\n\t\t\tthis.counts[event]--;\n\t\t\tif (this.counts[event] === 0) {\n\t\t\t\tdelete this.subscribers[event];\n\t\t\t\tdelete this.counts[event];\n\t\t\t\tif (this._onAllUnsubscribed) {\n\t\t\t\t\tthis._onAllUnsubscribed(event);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t};\n\n\temit = <K extends Extract<keyof Events, string>>(\n\t\tevent: K,\n\t\t...args: Parameters<Events[K]>\n\t) => {\n\t\tif (this._disabled) return;\n\t\tif (this.subscribers[event]) {\n\t\t\tObject.values(this.subscribers[event]).forEach((c) => c(...args));\n\t\t}\n\t};\n\n\tdispose = () => {\n\t\tthis._disabled = true;\n\t\tthis.disposed = true;\n\t\tconst events = Object.keys(this.subscribers);\n\t\tthis.subscribers = {} as any;\n\t\tthis.counts = {} as any;\n\t\tevents.forEach((event) => {\n\t\t\tif (this._onAllUnsubscribed) {\n\t\t\t\tthis._onAllUnsubscribed(event);\n\t\t\t}\n\t\t});\n\t};\n\n\tdisable = () => {\n\t\tthis._disabled = true;\n\t};\n}\n\nexport type EventsOf<T extends EventSubscriber<any>> =\n\tT extends EventSubscriber<infer E> ? keyof E : never;\n", "import {\n\tStorageCollectionSchema,\n\tStorageSyntheticIndexSchema,\n\tCollectionCompoundIndex,\n\tStorageDirectSyntheticSchema,\n} from './index.js';\n\n// unlikely to be used unicode character\nexport const COMPOUND_INDEX_SEPARATOR = '\\uFFFFFE';\n// 1 lower than separator\nexport const COMPOUND_INDEX_LOWER_BOUND_SEPARATOR = '\\u0000';\n// 1 higher than separator\nexport const COMPOUND_INDEX_UPPER_BOUND_SEPARATOR = '\\uFFFFFF';\n\ntype IndexableFieldValue = string | number | boolean | any[];\nexport type CompoundIndexValue = string | string[];\n\nexport function createCompoundIndexValue(\n\t...fields: IndexableFieldValue[]\n): CompoundIndexValue {\n\tconst value = expandArrayIndex(fields);\n\tif (value.length === 1) {\n\t\treturn value[0];\n\t}\n\treturn value;\n}\n\nexport function createUpperBoundIndexValue(\n\t...fields: IndexableFieldValue[]\n): string {\n\treturn (\n\t\tfields.join(COMPOUND_INDEX_SEPARATOR) +\n\t\t`${COMPOUND_INDEX_UPPER_BOUND_SEPARATOR}`\n\t);\n}\n\nexport function createLowerBoundIndexValue(\n\t...fields: IndexableFieldValue[]\n): string {\n\treturn (\n\t\tfields.join(COMPOUND_INDEX_SEPARATOR) +\n\t\t`${COMPOUND_INDEX_SEPARATOR}${COMPOUND_INDEX_LOWER_BOUND_SEPARATOR}`\n\t);\n}\n\n/**\n * Whenever an array value is included in a compound index, we have to expand\n * the value to include all permutations of values in the array.\n * For example if we had an index id + tags on a document\n *\n * {\n * id: '1',\n * tags: ['a', 'b']\n * }\n *\n * we want to create an index:\n *\n * id_tags: ['1#a', '1#b']\n *\n * If multiple arrays are indexed we have to exponentially expand...\n *\n * id_tags_tags2: ['1#a#a', '1#a#b', '1#b#a', '1#b#b']\n *\n * To generalize this we construct a 2-level array of strings.\n * Iterating over indexed values, we expand each item into N items if\n * the current value is an array.\n *\n * Then we combine all nested arrays into compound index values.\n * This will produce an array of 1 element if none of the indexed values\n * were arrays. The caller should unwrap that.\n *\n * This function also deduplicates values.\n */\nfunction expandArrayIndex(fields: IndexableFieldValue[]): string[] {\n\tlet value: string[][] = [[]];\n\tfor (const field of fields) {\n\t\tif (Array.isArray(field)) {\n\t\t\tconst newValue: string[][] = [];\n\t\t\tfor (const previousValue of value) {\n\t\t\t\tfor (const fieldValue of field) {\n\t\t\t\t\tnewValue.push(previousValue.concat(fieldValue));\n\t\t\t\t}\n\t\t\t}\n\t\t\tvalue = newValue;\n\t\t} else {\n\t\t\tfor (const item of value) {\n\t\t\t\titem.push(`${field}`);\n\t\t\t}\n\t\t}\n\t}\n\treturn Array.from(\n\t\tnew Set(\n\t\t\tvalue.map((item) => {\n\t\t\t\treturn item.join(COMPOUND_INDEX_SEPARATOR);\n\t\t\t}),\n\t\t),\n\t);\n}\n\nexport function isDirectSynthetic(\n\tindex: any,\n): index is StorageDirectSyntheticSchema<any> {\n\treturn !!index.field;\n}\n\nexport function computeSynthetics(schema: StorageCollectionSchema, obj: any) {\n\tconst result: Record<string, any> = {};\n\tfor (const [name, property] of Object.entries(schema.indexes || {})) {\n\t\tconst index = property as StorageSyntheticIndexSchema<any>;\n\t\tif (isDirectSynthetic(index)) {\n\t\t\tresult[name] = sanitizeIndexValue(obj[index.field]);\n\t\t} else {\n\t\t\tresult[name] = sanitizeIndexValue(index.compute(obj));\n\t\t}\n\t}\n\treturn result;\n}\n\nexport function computeCompoundIndices(\n\tschema: StorageCollectionSchema<any, any, any>,\n\tdoc: any,\n): any {\n\treturn Object.entries(schema.compounds || {}).reduce<\n\t\tRecord<string, CompoundIndexValue>\n\t>((acc, [indexKey, index]) => {\n\t\tacc[indexKey] = createCompoundIndexValue(\n\t\t\t...(index as CollectionCompoundIndex<any, any>).of.map(\n\t\t\t\t(key) => doc[key] as string | number,\n\t\t\t),\n\t\t);\n\t\treturn acc;\n\t}, {} as Record<string, CompoundIndexValue>);\n}\n\nfunction computeIndexedFields(schema: StorageCollectionSchema, doc: any) {\n\treturn Object.entries(schema.fields).reduce<Record<string, any>>(\n\t\t(acc, [key, field]) => {\n\t\t\t// TODO: remove once I'm comfortable dropping 'indexed' support\n\t\t\tif ('indexed' in field) {\n\t\t\t\tacc[key] = sanitizeIndexValue(doc[key]);\n\t\t\t}\n\t\t\treturn acc;\n\t\t},\n\t\t{},\n\t);\n}\n\nexport function getIndexValues(\n\tschema: StorageCollectionSchema<any, any, any>,\n\tdoc: any,\n) {\n\tconst basicIndexes: any = {\n\t\t[schema.primaryKey]: doc[schema.primaryKey],\n\t\t...computeIndexedFields(schema, doc),\n\t\t...computeSynthetics(schema, doc),\n\t};\n\tObject.assign(\n\t\tbasicIndexes,\n\t\tcomputeCompoundIndices(schema, { ...doc, ...basicIndexes }),\n\t);\n\treturn basicIndexes;\n}\n\nexport function assignIndexValues(\n\tschema: StorageCollectionSchema<any, any, any>,\n\tdoc: any,\n) {\n\tObject.assign(doc, computeSynthetics(schema, doc));\n\tObject.assign(doc, computeCompoundIndices(schema, doc));\n\treturn doc;\n}\n\nexport const NULL_INDEX_VALUE = 'null';\n\nexport function sanitizeIndexValue(\n\tvalue: unknown,\n): string | number | (string | number)[] {\n\tif (value === null) {\n\t\treturn NULL_INDEX_VALUE;\n\t}\n\tif (typeof value === 'string' || typeof value === 'number') {\n\t\treturn value;\n\t}\n\tif (typeof value === 'boolean' || value === null) {\n\t\treturn `${value}`;\n\t}\n\tif (value === undefined) {\n\t\t// this shouldn't happen ,but for resiliency...\n\t\treturn 'undefined';\n\t}\n\tif (Array.isArray(value)) {\n\t\treturn value.map(sanitizeIndexValue) as any;\n\t}\n\tthrow new Error(`Unsupported index value: ${value}`);\n}\n", "/**\n * Memoizes the last invocation of a function with the same memo keys.\n * As long as key identity and set doesn't change, the last computed\n * value will be returned.\n */\nexport function memoByKeys<TRet, TKeys extends any[]>(\n\tfn: (...args: unknown[]) => TRet,\n\tgetKeys: () => TKeys,\n): (...args: unknown[]) => TRet {\n\tlet cachedKeys: TKeys | undefined;\n\tlet cachedResult: TRet | undefined;\n\treturn (...args: unknown[]) => {\n\t\tconst keys = getKeys();\n\t\tif (\n\t\t\tcachedKeys &&\n\t\t\tcachedKeys.length === keys.length &&\n\t\t\tcachedKeys.every((key, i) => key === keys[i])\n\t\t) {\n\t\t\treturn cachedResult!;\n\t\t}\n\t\tcachedKeys = [...keys] as TKeys;\n\t\tcachedResult = fn(...args);\n\t\treturn cachedResult;\n\t};\n}\n", "import {\n\taddFieldDefaults,\n\tassert,\n\tassignOid,\n\tAuthorizationKey,\n\tCollectionFilter,\n\tgetOid,\n\tisMultiValueIndex,\n\tisRequired,\n\tremoveExtraProperties,\n\tstableStringify,\n\tStorageCollectionSchema,\n\tStorageDocument,\n\tStorageDocumentInit,\n\tStorageSchema,\n\tvalidateEntity,\n} from './index.js';\n\n/**@deprecated */\nexport interface DroppedCollectionMigrationStrategy<\n\tOld extends StorageCollectionSchema<any, any, any>,\n> {\n\t(old: Old): void | Promise<void>;\n}\n/**@deprecated */\nexport interface PreservedCollectionMigrationStrategy<\n\tOld extends StorageCollectionSchema<any, any, any>,\n\tNew extends StorageCollectionSchema<any, any, any>,\n> {\n\t(\n\t\told: StorageDocument<Old>,\n\t): StorageDocument<New> | Promise<StorageDocument<New>>;\n}\n/** @deprecated */\ntype MigrationStrategy<\n\tOld extends StorageCollectionSchema<any, any, any>,\n\tNew extends StorageCollectionSchema<any, any, any>,\n> =\n\t| DroppedCollectionMigrationStrategy<Old>\n\t| PreservedCollectionMigrationStrategy<Old, New>;\n/** @deprecated */\nexport type MigrationsKeyedOnCollection<\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> =\n\t| PreservedCollectionMigrations<Old, New>\n\t| DroppedCollectionMigrations<Old, New>;\n\n/**@deprecated */\ntype NotInSchema<\n\tName extends string | number | symbol,\n\tSchema extends StorageSchema<any>,\n> = Name extends keyof Schema['collections'] ? never : Name;\n/** @deprecated */\ntype InSchema<\n\tName extends string | number | symbol,\n\tSchema extends StorageSchema<any>,\n> = Name extends keyof Schema['collections'] ? Name : never;\n/** @deprecated */\ntype DroppedCollections<\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> = {\n\t[Key in keyof Old['collections'] as NotInSchema<\n\t\tKey,\n\t\tNew\n\t>]: StorageCollectionSchema<any, any, any>;\n};\n/** @deprecated */\ntype PreservedCollections<\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> = {\n\t[Key in keyof Old['collections'] as InSchema<\n\t\tKey,\n\t\tNew\n\t>]: StorageCollectionSchema<any, any, any>;\n};\n/** @deprecated */\ntype DroppedCollectionMigrations<\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> = {\n\t[Key in keyof DroppedCollections<\n\t\tOld,\n\t\tNew\n\t>]: DroppedCollectionMigrationStrategy<Old['collections'][Key]>;\n};\n/** @deprecated */\ntype PreservedCollectionMigrations<\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> = {\n\t[Key in keyof PreservedCollections<\n\t\tOld,\n\t\tNew\n\t>]: PreservedCollectionMigrationStrategy<\n\t\tOld['collections'][Key],\n\t\tNew['collections'][Key]\n\t>;\n};\n\n/** @deprecated */\ntype StrategyFor<\n\tKey extends string,\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> = Key extends keyof New['collections']\n\t? PreservedCollectionMigrationStrategy<\n\t\t\tOld['collections'][Key],\n\t\t\tNew['collections'][Key]\n\t\t>\n\t: DroppedCollectionMigrationStrategy<Old['collections'][Key]>;\n\n/** @deprecated */\ntype DeprecatedMigrationRunner<\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> = <Collection extends Extract<keyof Old['collections'], string>>(\n\tcollection: Collection,\n\tstrategy: StrategyFor<Collection, Old, New>,\n) => Promise<void>;\n\n/** @deprecated */\ntype DeprecatedMigrationQueryMaker<\n\tCollection extends StorageCollectionSchema<any, any, any>,\n> = {\n\tget(primaryKey: string): Promise<StorageDocument<Collection> | undefined>;\n\tfindOne(\n\t\tquery: CollectionFilter,\n\t): Promise<StorageDocument<Collection> | undefined>;\n\tfindAll(query?: CollectionFilter): Promise<StorageDocument<Collection>[]>;\n};\n\n/** @deprecated */\ntype DeprecatedMigrationQueries<Old extends StorageSchema<any>> = {\n\t[Key in keyof Old['collections']]: DeprecatedMigrationQueryMaker<\n\t\tOld['collections'][Key]\n\t>;\n};\n\n/** @deprecated */\ntype DeprecatedMigrationMutations<New extends StorageSchema> = {\n\t[Key in keyof New['collections']]: {\n\t\tput(\n\t\t\tdocument: StorageDocumentInit<New['collections'][Key]>,\n\t\t): Promise<StorageDocument<New['collections'][Key]>>;\n\t\tdelete(primaryKey: string): Promise<void>;\n\t};\n};\n/** @deprecated */\nexport interface DeprecatedMigrationTools<\n\tOld extends StorageSchema<any>,\n\tNew extends StorageSchema<any>,\n> {\n\tmigrate: DeprecatedMigrationRunner<Old, New>;\n\tidentity: <T>(val: T) => T;\n\t/**\n\t * @deprecated - default field values are automatically\n\t * applied during migration, you don't need to use this.\n\t * Please remove it from your migrations - even old ones\n\t * (old migrations can be updated!)\n\t */\n\twithDefaults: (collectionName: string, value: any) => any;\n\tqueries: DeprecatedMigrationQueries<Old>;\n\tmutations: DeprecatedMigrationMutations<New>;\n\tinfo: {\n\t\tchangedCollections: keyof Old['collections'][];\n\t\taddedCollections: keyof New['collections'][];\n\t\tremovedCollections: keyof Old['collections'][];\n\t};\n}\n\nexport interface MigrationEngine {\n\tmigrate: (collection: string, strategy: (val: any) => any) => Promise<void>;\n\tqueries: MigrationQueries<any>;\n\tmutations: MigrationMutations<any>;\n\t/** OIDs of any new documents created during the migration */\n\tnewOids: string[];\n\t/** Promises that should be resolved before completing the migration */\n\tawaitables: Promise<any>[];\n\t/** Deletes all documents in a collection - used for removed collections */\n\tdeleteCollection: (collection: string) => Promise<void>;\n\tlog: (...messages: any[]) => void;\n\tclose: () => Promise<void>;\n}\n/** @deprecated */\ntype DeprecatedMigrationProcedure<\n\tOld extends StorageSchema,\n\tNew extends StorageSchema,\n> = (tools: DeprecatedMigrationTools<Old, New>) => Promise<void>;\n\ntype EmptySchema = {\n\tversion: 0;\n\tcollections: {};\n};\nconst emptySchema: EmptySchema = {\n\tversion: 0,\n\tcollections: {},\n};\n\n/** @deprecated - use createMigration */\nexport function migrate<Schema extends StorageSchema>(\n\tschema: Schema,\n\tprocedure: DeprecatedMigrationProcedure<EmptySchema, Schema>,\n): Migration<EmptySchema, Schema>;\n/** @deprecated = use createMigration */\nexport function migrate<Old extends StorageSchema, New extends StorageSchema>(\n\toldSchema: Old,\n\tnewSchema: New,\n\tprocedure: DeprecatedMigrationProcedure<Old, New>,\n): Migration<Old, New>;\nexport function migrate(\n\toldSchemaOrNewSchema: any,\n\tnewSchemaOrProcedure: any,\n\tprocedureIfTwoSchemas?: any,\n) {\n\tconst isProcedureSecondArgument = typeof newSchemaOrProcedure === 'function';\n\tconst oldSchema = isProcedureSecondArgument\n\t\t? emptySchema\n\t\t: oldSchemaOrNewSchema;\n\tconst newSchema = isProcedureSecondArgument\n\t\t? oldSchemaOrNewSchema\n\t\t: newSchemaOrProcedure;\n\tconst procedure = isProcedureSecondArgument\n\t\t? newSchemaOrProcedure\n\t\t: procedureIfTwoSchemas;\n\t// diff to determine changed collections\n\tconst changedCollections: string[] = Object.keys(\n\t\tnewSchema.collections,\n\t).filter(\n\t\t(key) =>\n\t\t\toldSchema.collections[key] &&\n\t\t\tstableStringify(oldSchema.collections[key]) !==\n\t\t\t\tstableStringify(newSchema.collections[key]),\n\t);\n\tconst removedCollections: string[] = Object.keys(\n\t\toldSchema.collections,\n\t).filter((key) => !newSchema.collections[key]);\n\tconst addedCollections = Object.keys(newSchema.collections).filter(\n\t\t(key) => !oldSchema.collections[key],\n\t);\n\t// collections which added one or more field defaults\n\tconst autoMigratedCollections = new Set<string>();\n\tfor (const collection of changedCollections) {\n\t\tconst oldFields = oldSchema.collections[collection].fields;\n\t\tconst newFields = newSchema.collections[collection].fields;\n\t\t// a new default was added - we can auto-migrate it\n\t\tif (\n\t\t\tObject.keys(newFields).some(\n\t\t\t\t(key) => !oldFields[key]?.default && newFields[key]?.default,\n\t\t\t)\n\t\t) {\n\t\t\tautoMigratedCollections.add(collection);\n\t\t}\n\t\t// a field was removed - we can auto-migrate it\n\t\tif (Object.keys(oldFields).some((key) => !newFields[key])) {\n\t\t\tautoMigratedCollections.add(collection);\n\t\t}\n\t}\n\n\tconst addedIndexes: Record<string, MigrationIndexDescription[]> = {};\n\tconst removedIndexes: Record<string, MigrationIndexDescription[]> = {};\n\tfor (const changed of [...changedCollections, ...addedCollections]) {\n\t\tconst oldIndexes = getIndexes(oldSchema.collections[changed]);\n\t\tconst newIndexes = getIndexes(newSchema.collections[changed]);\n\t\tconst added = newIndexes.filter(\n\t\t\t(index) => !oldIndexes.find((i) => i.name === index.name),\n\t\t);\n\t\tconst removed = oldIndexes.filter(\n\t\t\t(index) => !newIndexes.find((i) => i.name === index.name),\n\t\t);\n\t\tif (added.length > 0) {\n\t\t\taddedIndexes[changed] = added;\n\t\t\t// FIXME: don't o(n^2) this\n\t\t\tif (changedCollections.includes(changed)) {\n\t\t\t\tautoMigratedCollections.add(changed);\n\t\t\t}\n\t\t}\n\t\tif (removed.length > 0) {\n\t\t\tremovedIndexes[changed] = removed;\n\t\t\t// FIXME: don't o(n^2) this\n\t\t\tif (changedCollections.includes(changed)) {\n\t\t\t\tautoMigratedCollections.add(changed);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst withDefaults = (collectionName: string, val: any) => {\n\t\treturn addFieldDefaults(newSchema.collections[collectionName], val);\n\t};\n\tconst autoMigration = (collectionName: string) => (val: any) => {\n\t\tconst collection = newSchema.collections[collectionName];\n\t\treturn addFieldDefaults(collection, removeExtraProperties(collection, val));\n\t};\n\n\treturn {\n\t\tversion: newSchema.version,\n\t\tmigrate: async (engine: MigrationEngine) => {\n\t\t\tconst migratedCollections: string[] = [];\n\t\t\tawait procedure({\n\t\t\t\tmigrate: async (collection: any, strategy: any) => {\n\t\t\t\t\tconst auto = autoMigration(collection);\n\t\t\t\t\tconst wrapped = async (val: any) => {\n\t\t\t\t\t\tconst baseValue = await strategy(val);\n\t\t\t\t\t\t// assign OID from original value in case user's strategy\n\t\t\t\t\t\t// involves cloning\n\t\t\t\t\t\tassignOid(baseValue, getOid(val));\n\t\t\t\t\t\tconst result = auto(baseValue);\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t};\n\t\t\t\t\t// @ts-ignore\n\t\t\t\t\tawait engine.migrate(collection, wrapped);\n\t\t\t\t\tmigratedCollections.push(collection);\n\t\t\t\t\t// since the user migrated this one and we wrap their\n\t\t\t\t\t// strategy with auto-migration, we can remove it from\n\t\t\t\t\t// the auto-migration list\n\t\t\t\t\tautoMigratedCollections.delete(collection);\n\t\t\t\t},\n\t\t\t\tidentity: (val: any) => val,\n\t\t\t\twithDefaults,\n\t\t\t\tinfo: {\n\t\t\t\t\tchangedCollections,\n\t\t\t\t\taddedCollections,\n\t\t\t\t\tremovedCollections,\n\t\t\t\t},\n\t\t\t\tqueries: engine.queries,\n\t\t\t\tmutations: engine.mutations,\n\t\t\t});\n\n\t\t\t// mandatory migration of fields which had defaults added or\n\t\t\t// fields removed but weren't migrated by the user\n\n\t\t\tif (newSchema.version > 1) {\n\t\t\t\tengine.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'auto-migrating collections with new defaults',\n\t\t\t\t\tautoMigratedCollections,\n\t\t\t\t);\n\t\t\t\tfor (const name of autoMigratedCollections) {\n\t\t\t\t\tawait engine.migrate(name, autoMigration(name));\n\t\t\t\t\tmigratedCollections.push(name);\n\t\t\t\t}\n\n\t\t\t\tconst unmigrated = changedCollections.filter(\n\t\t\t\t\t(collection) => !migratedCollections.includes(collection),\n\t\t\t\t);\n\t\t\t\tif (unmigrated.length > 0) {\n\t\t\t\t\t// TODO: does this deserve a full-on error?\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`Unmigrated changed collections from version ${oldSchema.version} to version ${newSchema.version}:`,\n\t\t\t\t\t\tunmigrated,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tremovedCollections,\n\t\taddedIndexes,\n\t\tremovedIndexes,\n\t\tallCollections: Object.keys(newSchema.collections),\n\t\tchangedCollections,\n\t\taddedCollections,\n\t\toldCollections: Object.keys(oldSchema.collections),\n\t\toldSchema,\n\t\tnewSchema,\n\t};\n}\n\nexport interface MigrationIndexDescription {\n\tname: string;\n\t/**\n\t * The index writes multiple entries. Any value which matches\n\t * a lookup on this index should return the associated document.\n\t */\n\tmultiEntry: boolean;\n\t/**\n\t * Whether this index is a synthetic index. Synthetic indexes are\n\t * computed from other fields.\n\t */\n\tsynthetic: boolean;\n\t/**\n\t * Whether this index is a compound index. Compound indexes are\n\t * created from multiple fields in the collection merged into one\n\t * value.\n\t */\n\tcompound: boolean;\n\t/**\n\t * The base type of the values for this index. Multientry indexes\n\t * store multiple values of this type.\n\t */\n\ttype: 'string' | 'number' | 'boolean';\n}\n\nexport interface Migration<\n\tOld extends StorageSchema = any,\n\tNew extends StorageSchema = any,\n> {\n\tversion: number;\n\toldSchema: Old;\n\tnewSchema: New;\n\tmigrate: (engine: MigrationEngine) => Promise<void>;\n\t/** Collections which are added in the new schema and not present in the old */\n\taddedCollections: string[];\n\t/** Collections which were removed from the old schema */\n\tremovedCollections: string[];\n\t/** All collections which exist after the migration has completed - i.e. the ones in the new schema */\n\tallCollections: string[];\n\t/** Only the collections which were in the old schema */\n\toldCollections: string[];\n\t/** Collections whose fields or indexes changed between schemas */\n\tchangedCollections: string[];\n\t// new indexes mapped by collection name\n\taddedIndexes: Record<string, MigrationIndexDescription[]>;\n\t// removed indexes mapped by collection name\n\tremovedIndexes: Record<string, MigrationIndexDescription[]>;\n}\n\nexport function migrationRange(from: number, to: number) {\n\treturn [...Array(to - from).keys()].map((i) => 1 + i + from);\n}\n\nfunction getIndexes<Coll extends StorageCollectionSchema<any, any, any>>(\n\tcollection: Coll | undefined,\n): MigrationIndexDescription[] {\n\tif (!collection) return [];\n\n\treturn [\n\t\t...Object.keys(collection.indexes || {}).map((key) => {\n\t\t\t// lookup name-based indexes to get type from original\n\t\t\t// field.\n\t\t\tconst index = collection.indexes[key];\n\t\t\tlet indexType = index.type;\n\t\t\tif (!indexType && index.field) {\n\t\t\t\tindexType = collection.fields[index.field].type;\n\t\t\t}\n\t\t\tassert(\n\t\t\t\tindexType,\n\t\t\t\t`Could not determine type of index ${collection}.${key}. Index must have a type. Perhaps your schema is malformed?`,\n\t\t\t);\n\n\t\t\tconst multiEntry = isMultiValueIndex(collection, key);\n\n\t\t\treturn {\n\t\t\t\tname: key,\n\t\t\t\tmultiEntry,\n\t\t\t\tsynthetic: true,\n\t\t\t\tcompound: false,\n\t\t\t\ttype: indexType?.replace('[]', '') as any,\n\t\t\t};\n\t\t}),\n\t\t...Object.keys(collection.compounds || {}).map((key) => ({\n\t\t\tname: key,\n\t\t\tmultiEntry: isMultiValueIndex(collection, key),\n\t\t\tsynthetic: false,\n\t\t\tcompound: true,\n\t\t\ttype: 'string' as const,\n\t\t})),\n\t];\n}\n\n/** @deprecated - use createMigration with no procedure function */\nexport function createDefaultMigration(\n\tschema: StorageSchema,\n): Migration<{ version: 0; collections: {} }>;\n/** @deprecated - use createMigration with no procedure function */\nexport function createDefaultMigration<Old extends StorageSchema>(\n\toldSchema: Old,\n\tnewSchema: StorageSchema,\n): Migration<Old>;\nexport function createDefaultMigration(\n\tschema: StorageSchema,\n\tnewSchema?: StorageSchema<any>,\n) {\n\tlet oldSchema = newSchema\n\t\t? schema\n\t\t: {\n\t\t\t\tversion: 0,\n\t\t\t\tcollections: {},\n\t\t\t};\n\treturn migrate(oldSchema, newSchema || schema, async ({ migrate, info }) => {\n\t\tif ((newSchema || schema).version === 1) return;\n\n\t\tfor (const collection of info.changedCollections as any) {\n\t\t\t// @ts-ignore indefinite type resolution\n\t\t\tawait migrate(collection, (old) => old);\n\t\t}\n\t});\n}\n\n/** New, simpler type-safety migration tools */\ntype DocumentShape<Init = any, Snapshot = any> = {\n\tinit: Init;\n\tsnapshot: Snapshot;\n};\ntype SchemaDocuments = Record<string, DocumentShape>;\ntype CollectionProcedure<OldSnapshot, NewInit> = {\n\t(old: OldSnapshot): NewInit | Promise<NewInit>;\n};\ntype MigrationQueries<Old extends SchemaDocuments> = {\n\t[Key in keyof Old]: {\n\t\tget(primaryKey: string): Promise<Old[Key]['snapshot'] | undefined>;\n\t\tfindOne(query: CollectionFilter): Promise<Old[Key]['snapshot'] | undefined>;\n\t\tfindAll(query?: CollectionFilter): Promise<Old[Key]['snapshot'][]>;\n\t};\n};\ntype MigrationMutations<New extends SchemaDocuments> = {\n\t[Key in keyof New]: {\n\t\tput(\n\t\t\tdocument: New[Key]['init'],\n\t\t\toptions?: { access?: AuthorizationKey },\n\t\t): Promise<New[Key]['snapshot']>;\n\t\tdelete(primaryKey: string): Promise<void>;\n\t};\n};\ntype MigrationTools<\n\tOld extends SchemaDocuments,\n\tNew extends SchemaDocuments,\n> = {\n\t/**\n\t * Process a change in a collection's documents by taking in each existing\n\t * document and returning its new shape. This is typed so you can be\n\t * confident the proper transformations are made.\n\t */\n\tmigrate: <Collection extends keyof Old & keyof New>(\n\t\tcollection: Collection,\n\t\tstrategy: CollectionProcedure<\n\t\t\tOld[Collection]['snapshot'],\n\t\t\tNew[Collection]['init']\n\t\t>,\n\t) => Promise<void>;\n\tmutations: MigrationMutations<New>;\n\tqueries: MigrationQueries<Old>;\n\tinfo: {\n\t\tchangedCollections: (keyof Old & keyof New)[];\n\t\taddedCollections: (keyof New)[];\n\t\tremovedCollections: (keyof Old)[];\n\t};\n};\ntype MigrationProcedure<\n\tOld extends SchemaDocuments,\n\tNew extends SchemaDocuments,\n> = {\n\t(tools: MigrationTools<Old, New>): Promise<void>;\n};\ntype InitialMigrationTools<New extends SchemaDocuments> = {\n\tmutations: MigrationMutations<New>;\n};\ntype InitialMigrationProcedure<New extends SchemaDocuments> = {\n\t(tools: InitialMigrationTools<New>): Promise<void>;\n};\n\nexport function createMigration<New extends SchemaDocuments>(\n\tnewSchema: StorageSchema,\n\tprocedure?: InitialMigrationProcedure<New>,\n): any;\nexport function createMigration<\n\tOld extends SchemaDocuments,\n\tNew extends SchemaDocuments,\n>(\n\toldSchema: StorageSchema,\n\tnewSchema: StorageSchema,\n\tprocedure?: MigrationProcedure<Old, New>,\n): any;\nexport function createMigration(\n\tmaybeOldSchema: StorageSchema,\n\tmaybeNewSchemaOrProcedure?:\n\t\t| StorageSchema\n\t\t| InitialMigrationProcedure<SchemaDocuments>,\n\tmaybeProcedure?: MigrationProcedure<SchemaDocuments, SchemaDocuments>,\n): any {\n\tconst isProcedureSecondArgument =\n\t\ttypeof maybeNewSchemaOrProcedure === 'function' ||\n\t\tmaybeNewSchemaOrProcedure === undefined;\n\tconst oldSchema = isProcedureSecondArgument ? emptySchema : maybeOldSchema;\n\tconst newSchema = isProcedureSecondArgument\n\t\t? maybeOldSchema\n\t\t: maybeNewSchemaOrProcedure;\n\tconst procedure = isProcedureSecondArgument\n\t\t? maybeNewSchemaOrProcedure\n\t\t: maybeProcedure;\n\tassert(oldSchema, 'Invalid arguments to createMigration');\n\tassert(newSchema, 'Invalid arguments to createMigration');\n\tconst {\n\t\tchangedCollections,\n\t\taddedCollections,\n\t\tremovedCollections,\n\t\taddedIndexes,\n\t\tremovedIndexes,\n\t\tautoMigratedCollections,\n\t\tautoMigration,\n\t} = getMigrationInfo(oldSchema, newSchema);\n\n\treturn {\n\t\tversion: newSchema.version,\n\t\tmigrate: async (engine: MigrationEngine) => {\n\t\t\tconst migratedCollections: string[] = [];\n\t\t\tconst migrate = async (collection: any, strategy: any) => {\n\t\t\t\tconst auto = autoMigration(collection);\n\t\t\t\tconst wrapped = async (val: any) => {\n\t\t\t\t\tconst baseValue = await strategy(val);\n\t\t\t\t\t// assign OID from original value in case user's strategy\n\t\t\t\t\t// involves cloning\n\t\t\t\t\tassignOid(baseValue, getOid(val));\n\t\t\t\t\tconst result = auto(baseValue);\n\t\t\t\t\tconst validationError = validateEntity(\n\t\t\t\t\t\tnewSchema.collections[collection].fields,\n\t\t\t\t\t\tresult,\n\t\t\t\t\t);\n\t\t\t\t\tif (validationError) {\n\t\t\t\t\t\t// TODO: what? throw?\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t};\n\t\t\t\t// @ts-ignore\n\t\t\t\tawait engine.migrate(collection, wrapped);\n\t\t\t\tmigratedCollections.push(collection);\n\t\t\t\t// since the user migrated this one and we wrap their\n\t\t\t\t// strategy with auto-migration, we can remove it from\n\t\t\t\t// the auto-migration list\n\t\t\t\tautoMigratedCollections.delete(collection);\n\t\t\t};\n\t\t\tawait procedure?.({\n\t\t\t\tmigrate,\n\t\t\t\tinfo: {\n\t\t\t\t\tchangedCollections,\n\t\t\t\t\taddedCollections,\n\t\t\t\t\tremovedCollections,\n\t\t\t\t},\n\t\t\t\tqueries: engine.queries,\n\t\t\t\tmutations: engine.mutations,\n\t\t\t});\n\n\t\t\t// mandatory migration of fields which had defaults added or\n\t\t\t// fields removed but weren't migrated by the user\n\n\t\t\tif (newSchema.version > 1) {\n\t\t\t\tengine.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'auto-migrating collections with new defaults',\n\t\t\t\t\tautoMigratedCollections,\n\t\t\t\t);\n\t\t\t\tfor (const name of autoMigratedCollections) {\n\t\t\t\t\tawait engine.migrate(name, autoMigration(name));\n\t\t\t\t\tmigratedCollections.push(name);\n\t\t\t\t}\n\n\t\t\t\t// delete all documents in deleted collections\n\t\t\t\tfor (const name of removedCollections) {\n\t\t\t\t\tawait engine.deleteCollection(name);\n\t\t\t\t}\n\n\t\t\t\tconst unmigrated = changedCollections.filter(\n\t\t\t\t\t(collection) => !migratedCollections.includes(collection),\n\t\t\t\t);\n\t\t\t\tif (unmigrated.length > 0) {\n\t\t\t\t\t// TODO: does this deserve a full-on error?\n\t\t\t\t\tengine.log(\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t`Unmigrated changed collections from version ${oldSchema.version} to version ${newSchema.version}:`,\n\t\t\t\t\t\tunmigrated,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tremovedCollections,\n\t\taddedIndexes,\n\t\tremovedIndexes,\n\t\tallCollections: Object.keys(newSchema.collections),\n\t\tchangedCollections,\n\t\taddedCollections,\n\t\toldCollections: Object.keys(oldSchema.collections),\n\t\toldSchema,\n\t\tnewSchema,\n\t};\n}\n\n// common tools\nfunction getMigrationInfo(oldSchema: StorageSchema, newSchema: StorageSchema) {\n\tconst changedCollections: string[] = Object.keys(\n\t\tnewSchema.collections,\n\t).filter(\n\t\t(key) =>\n\t\t\toldSchema.collections[key] &&\n\t\t\tstableStringify(oldSchema.collections[key]) !==\n\t\t\t\tstableStringify(newSchema.collections[key]),\n\t);\n\tconst removedCollections: string[] = Object.keys(\n\t\toldSchema.collections,\n\t).filter((key) => !newSchema.collections[key]);\n\tconst addedCollections = Object.keys(newSchema.collections).filter(\n\t\t(key) => !oldSchema.collections[key],\n\t);\n\t// collections which added one or more field defaults\n\tconst autoMigratedCollections = new Set<string>();\n\tfor (const collection of changedCollections) {\n\t\tconst oldFields = oldSchema.collections[collection].fields;\n\t\tconst newFields = newSchema.collections[collection].fields;\n\t\t// a new default was added - we can auto-migrate it\n\t\tif (\n\t\t\tObject.keys(newFields).some(\n\t\t\t\t(key) =>\n\t\t\t\t\t(!oldFields[key] || isRequired(oldFields[key])) &&\n\t\t\t\t\t!isRequired(newFields[key]),\n\t\t\t)\n\t\t) {\n\t\t\tautoMigratedCollections.add(collection);\n\t\t}\n\t\t// a field was removed - we can auto-migrate it\n\t\tif (Object.keys(oldFields).some((key) => !newFields[key])) {\n\t\t\tautoMigratedCollections.add(collection);\n\t\t}\n\t}\n\n\tconst addedIndexes: Record<string, MigrationIndexDescription[]> = {};\n\tconst removedIndexes: Record<string, MigrationIndexDescription[]> = {};\n\tfor (const changed of [...changedCollections, ...addedCollections]) {\n\t\tconst oldIndexes = getIndexes(oldSchema.collections[changed]);\n\t\tconst newIndexes = getIndexes(newSchema.collections[changed]);\n\t\tconst added = newIndexes.filter(\n\t\t\t(index) => !oldIndexes.find((i) => i.name === index.name),\n\t\t);\n\t\tconst removed = oldIndexes.filter(\n\t\t\t(index) => !newIndexes.find((i) => i.name === index.name),\n\t\t);\n\t\tif (added.length > 0) {\n\t\t\taddedIndexes[changed] = added;\n\t\t\t// FIXME: don't o(n^2) this\n\t\t\tif (changedCollections.includes(changed)) {\n\t\t\t\tautoMigratedCollections.add(changed);\n\t\t\t}\n\t\t}\n\t\tif (removed.length > 0) {\n\t\t\tremovedIndexes[changed] = removed;\n\t\t\t// FIXME: don't o(n^2) this\n\t\t\tif (changedCollections.includes(changed)) {\n\t\t\t\tautoMigratedCollections.add(changed);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst withDefaults = (collectionName: string, val: any) => {\n\t\treturn addFieldDefaults(newSchema.collections[collectionName], val);\n\t};\n\tconst autoMigration = (collectionName: string) => (val: any) => {\n\t\tconst collection = newSchema.collections[collectionName];\n\t\treturn addFieldDefaults(collection, removeExtraProperties(collection, val));\n\t};\n\n\treturn {\n\t\tchangedCollections,\n\t\taddedCollections,\n\t\tremovedCollections,\n\t\taddedIndexes,\n\t\tremovedIndexes,\n\t\tautoMigratedCollections,\n\t\twithDefaults,\n\t\tautoMigration,\n\t};\n}\n", "export interface UserInfo<Profile, Presence> {\n\t/**\n\t * This is the ID representing the user who is utilizing a\n\t * replica client to connect to the storage network.\n\t * One user may have multiple replica clients active at once,\n\t * but their presence will only reflect the most recent\n\t * replica used.\n\t */\n\tid: string;\n\t/**\n\t * This is the ID representing the replica client that is\n\t * connected to the storage network. This is used to\n\t * identify the client when sending messages to it.\n\t */\n\treplicaId: string;\n\n\t/**\n\t * This is the user's server profile. This data is associated\n\t * with the logged in user of the app and cannot be modified\n\t * by the local replica directly.\n\t */\n\tprofile: Profile;\n\n\t/**\n\t * Presence info which can update frequently as a replica\n\t * makes changes. The shape of presence is up to you.\n\t */\n\tpresence: Presence;\n\n\t/**\n\t * This is the internal presence data that Verdant uses\n\t * for some built-in presence functionality. The client\n\t * should manage it transparently to the user.\n\t */\n\tinternal: VerdantInternalPresence;\n}\n\nexport type UserInfoUpdate<Profile = any, Presence = any> = Omit<\n\tUserInfo<Profile, Presence>,\n\t'internal' | 'profile'\n> & {\n\tinternal?: VerdantInternalPresence;\n};\n\nexport interface VerdantInternalPresence {\n\tviewId?: string;\n\tlastFieldId?: string;\n\tlastFieldTimestamp?: number;\n}\n\nexport const initialInternalPresence: VerdantInternalPresence = {};\n", "export interface ReplicaInfo {\n\tid: string;\n\tackedLogicalTime: string | null;\n}\n\n/**\n * Different token types allow different replica client behaviors.\n * - Realtime: allows the client to subscribe to realtime events.\n * - Push: allows the client to push and pull data with HTTP, but not use realtime.\n * - PassivePush: allows the client to push and pull data with HTTP, but offline changes\n * will be discarded on reconnect.\n * - PassiveRealtime: allows the client to subscribe to realtime events, but offline changes\n * \t\t will be discarded on reconnect.\n * - ReadOnlyPull: the client may only pull changes using HTTP. It may not subscribe\n * to realtime events or push changes.\n * - ReadOnlyRealtime: the client may only subscribe to realtime events or pull from HTTP.\n * It may not push changes.\n *\n * Choosing the right token type can optimize client storage metrics significantly when\n * many replicas are connecting to a library.\n */\nexport enum ReplicaType {\n\tRealtime,\n\tPush,\n\tPassiveRealtime,\n\tPassivePush,\n\tReadOnlyPull,\n\tReadOnlyRealtime,\n}\n", "import cuid from 'cuid';\nimport {\n\tShapeFromFieldsWithDefaults,\n\tShapeFromProperty,\n\tStorageAnyFieldSchema,\n\tStorageArrayFieldSchema,\n\tStorageBooleanFieldSchema,\n\tStorageFieldSchema,\n\tStorageFieldsSchema,\n\tStorageFileFieldSchema,\n\tStorageMapFieldSchema,\n\tStorageNumberFieldSchema,\n\tStorageObjectFieldSchema,\n\tStorageStringFieldSchema,\n} from './types.js';\n\ntype ObjectFieldArgs<Props extends StorageFieldsSchema> = {\n\t/** @deprecated - use fields. renamed for more consistency with collection root. */\n\tproperties?: Props;\n\tfields?: Props;\n\tnullable?: boolean;\n\tdefault?:\n\t\t| ShapeFromFieldsWithDefaults<Props>\n\t\t| (() => ShapeFromFieldsWithDefaults<Props>);\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n};\n\nfunction objectField<Props extends StorageFieldsSchema>(\n\targs: ObjectFieldArgs<Props>,\n): StorageObjectFieldSchema<Props> {\n\tconst { properties, fields, ...resolvedArgs } = args;\n\tconst props = properties || fields;\n\tif (!props) {\n\t\tthrow new Error('objectField must be passed a properties object');\n\t}\n\treturn {\n\t\ttype: 'object',\n\t\t...resolvedArgs,\n\t\tproperties: props,\n\t};\n}\n\n/**\n * Used for recursively defined field schemas. Replaces the original properties\n * of an object field with the provided fields. This will mutate the original field.\n */\nfunction replaceObjectFields(\n\tobject: StorageObjectFieldSchema<any>,\n\tfields: StorageFieldsSchema,\n): StorageObjectFieldSchema<any> {\n\tobject.properties = fields;\n\treturn object;\n}\n\ntype ArrayFieldArgs<T extends StorageFieldSchema> = {\n\titems: T;\n\tnullable?: boolean;\n\tdefault?: ShapeFromProperty<T>[] | (() => ShapeFromProperty<T>[]);\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n};\n\nfunction arrayField<T extends StorageFieldSchema>(\n\targs: ArrayFieldArgs<T>,\n): StorageArrayFieldSchema<T> {\n\treturn {\n\t\ttype: 'array',\n\t\t...args,\n\t};\n}\n\n/**\n * Used for recursively defined field schemas. Replaces the original items\n * of an array field with the provided items. This will mutate the original field.\n */\nfunction replaceArrayItems(\n\tarray: StorageArrayFieldSchema<any>,\n\titems: StorageFieldSchema,\n): StorageArrayFieldSchema<any> {\n\tarray.items = items;\n\treturn array;\n}\n\nconst stringField = (args?: {\n\tnullable?: boolean;\n\tdefault?: string | (() => string);\n\toptions?: string[];\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n}): StorageStringFieldSchema => {\n\treturn {\n\t\ttype: 'string',\n\t\t...args,\n\t};\n};\n\nconst numberField = (args?: {\n\tnullable?: boolean;\n\tdefault?: number | (() => number);\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n}): StorageNumberFieldSchema => {\n\treturn {\n\t\ttype: 'number',\n\t\t...args,\n\t};\n};\n\nconst booleanField = (args?: {\n\tnullable?: boolean;\n\tdefault?: boolean | (() => boolean);\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n}): StorageBooleanFieldSchema => {\n\treturn {\n\t\ttype: 'boolean',\n\t\t...args,\n\t};\n};\n\nconst anyField = <TShape>(args?: {\n\tdefault?: TShape;\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n}): StorageAnyFieldSchema<TShape> => {\n\treturn {\n\t\ttype: 'any',\n\t\t...args,\n\t};\n};\n\ntype MapFieldArgs<T extends StorageFieldSchema> = {\n\tvalues: T;\n\tdefault?:\n\t\t| Record<string, ShapeFromProperty<T>>\n\t\t| (() => Record<string, ShapeFromProperty<T>>);\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n};\nfunction mapField<T extends StorageFieldSchema>(\n\targs: MapFieldArgs<T>,\n): StorageMapFieldSchema<T> {\n\treturn {\n\t\ttype: 'map',\n\t\t...args,\n\t};\n}\n\n/**\n * Used for recursively defined field schemas. Replaces the original values\n * of a map field with the provided values. This will mutate the original field.\n */\nfunction replaceMapValues(\n\tmap: StorageMapFieldSchema<any>,\n\tvalues: StorageFieldSchema,\n): StorageMapFieldSchema<any> {\n\tmap.values = values;\n\treturn map;\n}\n\nconst fileField = (args?: {\n\tnullable?: boolean;\n\tdownloadRemote?: boolean;\n\t/** Add some docs to your field which will annotate the generated typing */\n\tdocumentation?: string;\n}): StorageFileFieldSchema => {\n\treturn {\n\t\ttype: 'file',\n\t\t...args,\n\t};\n};\n\n/**\n * Meant for use on primary key fields. Do not use this to refer\n * to another document as a 'foreign key'\n */\nconst idField = (): StorageStringFieldSchema => {\n\treturn {\n\t\ttype: 'string',\n\t\tdefault: cuid,\n\t};\n};\n\nexport const fields = {\n\tobject: objectField,\n\tarray: arrayField,\n\treplaceObjectFields,\n\treplaceArrayItems,\n\tstring: stringField,\n\tnumber: numberField,\n\tboolean: booleanField,\n\tany: anyField,\n\tmap: mapField,\n\treplaceMapValues,\n\tfile: fileField,\n\tid: idField,\n};\n", "import {\n\tCollectionCompoundIndices,\n\tStorageCollectionSchema,\n\tStorageDirectSyntheticSchema,\n\tStorageFieldsSchema,\n\tStorageSchema,\n\tStorageSyntheticIndexSchema,\n\tStorageSyntheticIndices,\n} from './types.js';\nimport { fields } from './fieldHelpers.js';\nimport cuid from 'cuid';\n\nexport function collection<\n\tFields extends StorageFieldsSchema,\n\tSynthetics extends StorageSyntheticIndices<Fields>,\n\tCompounds extends CollectionCompoundIndices<Fields, Synthetics>,\n>({\n\tsynthetics,\n\tindexes,\n\t...input\n}: StorageCollectionSchema<\n\tFields,\n\tSynthetics,\n\tCompounds\n>): StorageCollectionSchema<Fields, Synthetics, Compounds> {\n\t// back compat - copy synthetics in with indexes\n\tconst finalIndexes = { ...synthetics, ...indexes };\n\t// add all indexed fields into the synthetic indices (back compat)\n\tfor (const [key, field] of Object.entries(input.fields)) {\n\t\tif ('indexed' in field) {\n\t\t\tfinalIndexes[key] = {\n\t\t\t\tfield: key,\n\t\t\t} as StorageDirectSyntheticSchema<Fields>;\n\t\t}\n\t}\n\treturn {\n\t\t...input,\n\t\tindexes: finalIndexes as Synthetics,\n\t};\n}\n\nexport function schema<\n\t// Fields extends StorageFieldsSchema,\n\t// Indexes extends StorageSyntheticIndices<Fields>,\n\t// Compounds extends CollectionCompoundIndices<Fields, Indexes>,\n\tSchema extends StorageSchema<{\n\t\t[key: string]: StorageCollectionSchema<any, any, any>;\n\t}>,\n>(input: Schema): StorageSchema {\n\treturn input;\n}\nschema.collection = collection;\nschema.fields = fields;\nschema.generated = {\n\tid: cuid,\n};\n\nexport * from './types.js';\n\nexport * from './indexFilters.js';\nexport * from './fields.js';\nexport * from './validation.js';\nexport * from './children.js';\n", "import {\n\tCollectionCompoundIndexFilter,\n\tCollectionFilter,\n\tMatchCollectionIndexFilter,\n\tRangeCollectionIndexFilter,\n\tSortIndexFilter,\n\tStartsWithIndexFilter,\n\tStorageCollectionSchema,\n} from './types.js';\n\nexport function isMatchIndexFilter(\n\tfilter: CollectionFilter,\n): filter is MatchCollectionIndexFilter {\n\treturn (filter as any).equals !== undefined;\n}\n\nexport function isRangeIndexFilter(\n\tfilter: CollectionFilter,\n): filter is RangeCollectionIndexFilter {\n\treturn (\n\t\t(filter as any).gte !== undefined ||\n\t\t(filter as any).lte !== undefined ||\n\t\t(filter as any).gt !== undefined ||\n\t\t(filter as any).lt !== undefined\n\t);\n}\n\nexport function isCompoundIndexFilter(\n\tfilter: CollectionFilter,\n): filter is CollectionCompoundIndexFilter {\n\treturn !!(filter as any).match;\n}\n\nexport function isStartsWithIndexFilter(\n\tfilter: CollectionFilter,\n): filter is StartsWithIndexFilter {\n\treturn (filter as any).startsWith !== undefined;\n}\n\nexport function isSortIndexFilter(\n\tfilter: CollectionFilter,\n): filter is SortIndexFilter {\n\treturn (\n\t\t!isRangeIndexFilter(filter) &&\n\t\t!isMatchIndexFilter(filter) &&\n\t\t!isCompoundIndexFilter(filter) &&\n\t\t!isStartsWithIndexFilter(filter) &&\n\t\t(filter as any).order\n\t);\n}\n\nexport function isMultiValueIndex(\n\tcollectionSchema: StorageCollectionSchema,\n\tindexName: string,\n): boolean {\n\tconst compound = collectionSchema.compounds?.[indexName];\n\tif (compound) {\n\t\treturn compound.of.some((fieldOrIndexName) => {\n\t\t\treturn isMultiValueIndex(collectionSchema, fieldOrIndexName);\n\t\t});\n\t}\n\tconst index = collectionSchema.indexes?.[indexName];\n\tif (index) {\n\t\tif ('type' in index) {\n\t\t\treturn isMultiEntryIndexType(index.type);\n\t\t}\n\t\tif ('field' in index) {\n\t\t\tconst field = collectionSchema.fields[index.field];\n\t\t\tif (!field) return false;\n\t\t\treturn isMultiEntryIndexType(field.type);\n\t\t}\n\t}\n\tconst field = collectionSchema.fields[indexName];\n\tif (!field) return false;\n\treturn isMultiEntryIndexType(field.type);\n}\n\nfunction isMultiEntryIndexType(type: string) {\n\treturn type === 'array' || type.endsWith('[]');\n}\n", "import { LEGACY_OID_KEY, OID_KEY } from '../oidsLegacy.js';\nimport { isObject } from '../utils.js';\nimport type {\n\tStorageCollectionSchema,\n\tStorageFieldSchema,\n\tStorageFieldsSchema,\n} from './types.js';\n\nexport function isNullable(field: StorageFieldSchema) {\n\tif (field.type === 'any') return true;\n\tif (field.type === 'map') return false;\n\treturn field.nullable;\n}\n\nexport function hasDefault(field: StorageFieldSchema | undefined) {\n\tif (!field) return false;\n\tif (field.type === 'map') return true;\n\tif (field.type === 'array') return true;\n\tif (field.type === 'file') return false;\n\treturn field.default !== undefined;\n}\n\nexport function isRequired(field: StorageFieldSchema) {\n\treturn !isNullable(field) && !hasDefault(field);\n}\n\nexport function isPrunePoint(field: StorageFieldSchema) {\n\treturn isNullable(field) || hasDefault(field);\n}\n\nexport function addFieldDefaults(\n\tcollection: StorageCollectionSchema,\n\tvalue: any,\n) {\n\tfor (const [key, field] of Object.entries(collection.fields)) {\n\t\tconst defaultValue = getFieldDefault(field);\n\t\tif (\n\t\t\t(defaultValue !== undefined && value[key] === undefined) ||\n\t\t\t// covers the case where a previously nullable field\n\t\t\t// now has a default during a new migration\n\t\t\t(!isNullable(field) && value[key] === null)\n\t\t) {\n\t\t\tvalue[key] = defaultValue;\n\t\t}\n\t\tif (value[key]) {\n\t\t\ttraverseCollectionFieldsAndApplyDefaults(value[key], field);\n\t\t}\n\t}\n\treturn value;\n}\n\nexport function traverseCollectionFieldsAndApplyDefaults(\n\tvalue: any,\n\tfield: StorageFieldSchema,\n) {\n\tif (value === undefined || value === null) return value;\n\tif (field.type === 'object') {\n\t\tfor (const [key, subField] of Object.entries(\n\t\t\tfield.properties as StorageFieldsSchema,\n\t\t)) {\n\t\t\tif (value[key] === undefined) {\n\t\t\t\tconst defaultValue = getFieldDefault(subField);\n\t\t\t\tif (defaultValue !== undefined) {\n\t\t\t\t\tvalue[key] = defaultValue;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttraverseCollectionFieldsAndApplyDefaults(value[key], subField);\n\t\t}\n\t} else if (field.type === 'array') {\n\t\tfor (const item of value) {\n\t\t\ttraverseCollectionFieldsAndApplyDefaults(item, field.items);\n\t\t}\n\t} else if (field.type === 'map') {\n\t\tfor (const [key, item] of Object.entries(value)) {\n\t\t\t// santiy check to weed out any id field\n\t\t\tif (key === OID_KEY || key === LEGACY_OID_KEY) continue;\n\t\t\ttraverseCollectionFieldsAndApplyDefaults(item, field.values);\n\t\t}\n\t}\n}\n\nexport function getFieldDefault(field: StorageFieldSchema): any {\n\tif ('default' in field) {\n\t\tconst val =\n\t\t\ttypeof field.default === 'function' ? field.default() : field.default;\n\t\tif (val === null) return val;\n\n\t\tconst cloned = structuredClone(val);\n\n\t\tif (field.type === 'object') {\n\t\t\t// objects also apply defaults of sub-fields over top of the default object\n\t\t\tfor (const [key, property] of Object.entries(\n\t\t\t\tfield.properties as StorageFieldsSchema,\n\t\t\t)) {\n\t\t\t\tif (cloned[key] === undefined) {\n\t\t\t\t\tcloned[key] = getFieldDefault(property);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn cloned;\n\t}\n\n\tif (isNullable(field)) {\n\t\treturn null;\n\t}\n\n\tif (field.type === 'array') {\n\t\treturn [];\n\t}\n\n\tif (field.type === 'map') {\n\t\treturn {};\n\t}\n\n\treturn undefined;\n}\n\nexport function removeExtraProperties(\n\tcollection: StorageCollectionSchema,\n\tvalue: any,\n) {\n\tfor (const [key, fieldValue] of Object.entries(value)) {\n\t\t// MUST NOT DELETE THESE!\n\t\tif (key === OID_KEY || key === LEGACY_OID_KEY) continue;\n\n\t\tif (!collection.fields[key]) {\n\t\t\tdelete value[key];\n\t\t} else {\n\t\t\ttraverseCollectionFieldsAndRemoveExtraProperties(\n\t\t\t\tfieldValue,\n\t\t\t\tcollection.fields[key],\n\t\t\t);\n\t\t}\n\t}\n\treturn value;\n}\n\nexport function traverseCollectionFieldsAndRemoveExtraProperties(\n\tvalue: any,\n\tfield: StorageFieldSchema,\n) {\n\tif (isObject(value) && field.type === 'object') {\n\t\tfor (const [key, fieldValue] of Object.entries(value)) {\n\t\t\tif (!field.properties[key]) {\n\t\t\t\tdelete value[key];\n\t\t\t} else {\n\t\t\t\ttraverseCollectionFieldsAndRemoveExtraProperties(\n\t\t\t\t\tfieldValue,\n\t\t\t\t\tfield.properties[key],\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t} else if (Array.isArray(value) && field.type === 'array') {\n\t\tfor (const item of value) {\n\t\t\ttraverseCollectionFieldsAndRemoveExtraProperties(item, field.items);\n\t\t}\n\t}\n}\n\nexport function isPrimitive(fieldSchema: StorageFieldSchema) {\n\treturn (\n\t\tfieldSchema.type === 'string' ||\n\t\tfieldSchema.type === 'number' ||\n\t\tfieldSchema.type === 'boolean'\n\t);\n}\n", "import { isFile, isFileData, isFileRef } from '../files.js';\nimport { OID_KEY } from '../oidsLegacy.js';\nimport { isObjectRef } from '../operation.js';\nimport { isObject } from '../utils.js';\nimport { hasDefault, isNullable } from './fields.js';\nimport { StorageFieldSchema, StorageFieldsSchema } from './types.js';\n\nexport function validateEntity(\n\tschema: StorageFieldsSchema,\n\tentity: any,\n): EntityValidationProblem | void {\n\tfor (const [key, value] of Object.entries(entity)) {\n\t\t// legacy -- old objects sometimes accidentally include this key\n\t\tif (key === OID_KEY) continue;\n\t\tif (!schema[key]) {\n\t\t\treturn {\n\t\t\t\ttype: 'invalid-key',\n\t\t\t\tfieldPath: [key],\n\t\t\t\tmessage: `Invalid field \"${key}\"`,\n\t\t\t};\n\t\t}\n\t\tif (value) {\n\t\t\tconst err = validateEntityField({\n\t\t\t\tfield: schema[key],\n\t\t\t\tvalue,\n\t\t\t\tfieldPath: [key],\n\t\t\t});\n\t\t\tif (err) return err;\n\t\t}\n\t}\n\treturn;\n}\n\nexport type EntityValidationProblem = {\n\ttype:\n\t\t| 'null'\n\t\t| 'no-default'\n\t\t| 'invalid-type'\n\t\t| 'invalid-value'\n\t\t| 'invalid-key';\n\tfieldPath: (string | number)[];\n\tmessage: string;\n};\n\nexport function validateEntityField({\n\tfield,\n\tvalue,\n\tfieldPath = [],\n\tdepth,\n\trequireDefaults,\n\texpectRefs,\n\thasPassedFirstLevel,\n}: {\n\tfield: StorageFieldSchema;\n\tvalue: any;\n\tfieldPath: (string | number)[];\n\tdepth?: number;\n\trequireDefaults?: boolean;\n\t/**\n\t * Run validation expecting refs, not nested objects. For validating\n\t * views (as opposed to inits/snapshots). Recommended to use depth 2\n\t * or no depth specified.\n\t */\n\texpectRefs?: boolean;\n\thasPassedFirstLevel?: boolean;\n}): EntityValidationProblem | undefined {\n\t// we only _actually_ start expecting refs after the first validation level.\n\t// TODO: something more... elegant?\n\tconst actuallyExpectRefs = expectRefs && hasPassedFirstLevel;\n\tif (depth !== undefined && depth <= 0) return;\n\n\tif (isNullable(field) && (value === null || value === undefined)) return;\n\tif (value === null || value === undefined) {\n\t\tif (requireDefaults || !hasDefault(field)) {\n\t\t\treturn {\n\t\t\t\ttype: 'no-default',\n\t\t\t\tfieldPath,\n\t\t\t\tmessage: `Invalid null value for field ${formatField(fieldPath)}`,\n\t\t\t};\n\t\t}\n\t}\n\n\tif (field.type === 'object') {\n\t\tif (actuallyExpectRefs) {\n\t\t\tif (!isObjectRef(value)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-type',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected ref for field ${formatField(\n\t\t\t\t\t\tfieldPath,\n\t\t\t\t\t)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t} else {\n\t\t\tif (!isObject(value)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-type',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected object ${\n\t\t\t\t\t\tfield.nullable ? 'or null ' : ''\n\t\t\t\t\t}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t\tfor (const [key, subField] of Object.entries(\n\t\t\t\tfield.properties as StorageFieldsSchema,\n\t\t\t)) {\n\t\t\t\t// legacy -- old objects sometimes accidentally include this key\n\t\t\t\tif (key === OID_KEY) continue;\n\t\t\t\tconst error = validateEntityField({\n\t\t\t\t\tfield: subField,\n\t\t\t\t\tvalue: value[key],\n\t\t\t\t\tfieldPath: [...fieldPath, key],\n\t\t\t\t\tdepth: depth !== undefined ? depth - 1 : undefined,\n\t\t\t\t\texpectRefs,\n\t\t\t\t\thasPassedFirstLevel: true,\n\t\t\t\t});\n\t\t\t\tif (error) {\n\t\t\t\t\treturn error;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// check for unexpected keys\n\t\t\tfor (const key of Object.keys(value)) {\n\t\t\t\tif (!field.properties[key]) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'invalid-key',\n\t\t\t\t\t\tfieldPath: [...fieldPath, key],\n\t\t\t\t\t\tmessage: `Invalid unexpected field \"${key}\" on value ${formatField(\n\t\t\t\t\t\t\tfieldPath,\n\t\t\t\t\t\t)}`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if (field.type === 'array') {\n\t\tif (actuallyExpectRefs) {\n\t\t\tif (!isObjectRef(value)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-type',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected ref for field ${formatField(\n\t\t\t\t\t\tfieldPath,\n\t\t\t\t\t)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t} else {\n\t\t\tif (!Array.isArray(value)) {\n\t\t\t\tif (value === null && field.nullable) return;\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-value',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected array ${\n\t\t\t\t\t\tfield.nullable ? 'or null ' : ''\n\t\t\t\t\t}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t\tfor (const item of value) {\n\t\t\t\tconst error = validateEntityField({\n\t\t\t\t\tfield: field.items,\n\t\t\t\t\tvalue: item,\n\t\t\t\t\tfieldPath: [...fieldPath, '[]'],\n\t\t\t\t\tdepth: depth !== undefined ? depth - 1 : undefined,\n\t\t\t\t\texpectRefs,\n\t\t\t\t\thasPassedFirstLevel: true,\n\t\t\t\t});\n\t\t\t\tif (error) {\n\t\t\t\t\treturn error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if (field.type === 'map') {\n\t\tif (actuallyExpectRefs) {\n\t\t\tif (!isObjectRef(value)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-type',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected ref for field ${formatField(\n\t\t\t\t\t\tfieldPath,\n\t\t\t\t\t)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t} else {\n\t\t\tif (!isObject(value)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-type',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected map for field ${formatField(\n\t\t\t\t\t\tfieldPath,\n\t\t\t\t\t)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t\tfor (const [key, item] of Object.entries(value)) {\n\t\t\t\tconst error = validateEntityField({\n\t\t\t\t\tfield: field.values,\n\t\t\t\t\tvalue: item,\n\t\t\t\t\tfieldPath: [...fieldPath, key],\n\t\t\t\t\tdepth: depth !== undefined ? depth - 1 : undefined,\n\t\t\t\t\texpectRefs,\n\t\t\t\t\thasPassedFirstLevel: true,\n\t\t\t\t});\n\t\t\t\tif (error) {\n\t\t\t\t\treturn error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if (field.type === 'string') {\n\t\tif (typeof value !== 'string') {\n\t\t\treturn {\n\t\t\t\ttype: 'invalid-type',\n\t\t\t\tfieldPath,\n\t\t\t\tmessage: `Expected string ${\n\t\t\t\t\tfield.nullable ? 'or null ' : ''\n\t\t\t\t}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,\n\t\t\t};\n\t\t}\n\t\tif (field.options && !field.options.includes(value)) {\n\t\t\treturn {\n\t\t\t\ttype: 'invalid-value',\n\t\t\t\tfieldPath,\n\t\t\t\tmessage: `Expected one of ${field.options.join(\n\t\t\t\t\t', ',\n\t\t\t\t)} for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,\n\t\t\t};\n\t\t}\n\t} else if (field.type === 'boolean') {\n\t\tif (typeof value !== 'boolean') {\n\t\t\treturn {\n\t\t\t\ttype: 'invalid-type',\n\t\t\t\tfieldPath,\n\t\t\t\tmessage: `Expected boolean ${\n\t\t\t\t\tfield.nullable ? 'or null ' : ''\n\t\t\t\t}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,\n\t\t\t};\n\t\t}\n\t} else if (field.type === 'number') {\n\t\tif (typeof value !== 'number') {\n\t\t\treturn {\n\t\t\t\ttype: 'invalid-type',\n\t\t\t\tfieldPath,\n\t\t\t\tmessage: `Expected number ${\n\t\t\t\t\tfield.nullable ? 'or null ' : ''\n\t\t\t\t}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,\n\t\t\t};\n\t\t}\n\t} else if (field.type === 'file') {\n\t\tif (actuallyExpectRefs) {\n\t\t\tif (!isFileRef(value)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-type',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected file ref for field ${formatField(\n\t\t\t\t\t\tfieldPath,\n\t\t\t\t\t)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t} else {\n\t\t\tif (!isFile(value) && !isFileData(value)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'invalid-type',\n\t\t\t\t\tfieldPath,\n\t\t\t\t\tmessage: `Expected file ${\n\t\t\t\t\t\tfield.nullable ? 'or null ' : ''\n\t\t\t\t\t}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction safeStringify(value: any) {\n\ttry {\n\t\treturn JSON.stringify(value);\n\t} catch (err) {\n\t\t// for example, recursive objects can't be stringified\n\t\treturn String(value);\n\t}\n}\n\nfunction formatField(fieldPath: (string | number)[]) {\n\tif (fieldPath.length === 0) return 'root';\n\treturn fieldPath.join('.');\n}\n\nexport function constrainEntity(schema: StorageFieldsSchema, entity: any): any {\n\tconst constrained: any = {};\n\tfor (const [key, value] of Object.entries(entity)) {\n\t\tif (!schema[key]) continue;\n\t\tconstrained[key] = constrainEntityField({\n\t\t\tfield: schema[key],\n\t\t\tvalue,\n\t\t\tfieldPath: [key],\n\t\t});\n\t}\n\treturn constrained;\n}\n\nexport function constrainEntityField({\n\tfield,\n\tvalue,\n\tfieldPath = [],\n\tdepth,\n}: {\n\tfield: StorageFieldSchema;\n\tvalue: any;\n\tfieldPath?: (string | number)[];\n\tdepth?: number;\n}): any {\n\tconst validationProblem = validateEntityField({\n\t\tfield,\n\t\tvalue,\n\t\tfieldPath,\n\t\tdepth,\n\t\trequireDefaults: true,\n\t});\n\n\tif (validationProblem) {\n\t\tthrow new Error(`Validation error: ${validationProblem.message}`);\n\t}\n\n\tif (field.type === 'object') {\n\t\tif (!isObject(value)) return value;\n\t\tconst constrained: any = {};\n\t\tfor (const [key, subField] of Object.entries(\n\t\t\tfield.properties as StorageFieldsSchema,\n\t\t)) {\n\t\t\tconstrained[key] = constrainEntityField({\n\t\t\t\tfield: subField,\n\t\t\t\tvalue: value[key],\n\t\t\t\tfieldPath: [...fieldPath, key],\n\t\t\t\tdepth: depth !== undefined ? depth - 1 : undefined,\n\t\t\t});\n\t\t}\n\t\treturn constrained;\n\t} else if (field.type === 'array') {\n\t\tif (!Array.isArray(value)) return value;\n\t\treturn value.map((item) =>\n\t\t\tconstrainEntityField({\n\t\t\t\tfield: field.items,\n\t\t\t\tvalue: item,\n\t\t\t\tfieldPath: [...fieldPath, '[]'],\n\t\t\t\tdepth: depth !== undefined ? depth - 1 : undefined,\n\t\t\t}),\n\t\t);\n\t} else if (field.type === 'map') {\n\t\tif (!isObject(value)) return value;\n\t\tconst constrained: any = {};\n\t\tfor (const [key, item] of Object.entries(value)) {\n\t\t\tconstrained[key] = constrainEntityField({\n\t\t\t\tfield: field.values,\n\t\t\t\tvalue: item,\n\t\t\t\tfieldPath: [...fieldPath, key],\n\t\t\t\tdepth: depth !== undefined ? depth - 1 : undefined,\n\t\t\t});\n\t\t}\n\t\treturn constrained;\n\t} else {\n\t\treturn value;\n\t}\n}\n", "import { StorageFieldSchema, StorageFieldsSchema } from './types.js';\n\nexport function getChildFieldSchema(\n\tschema: StorageFieldSchema | StorageFieldsSchema,\n\tkey: string | number,\n): StorageFieldSchema | null {\n\tif (schema.type === 'object') {\n\t\treturn schema.properties[key];\n\t} else if (schema.type === 'array') {\n\t\treturn schema.items;\n\t} else if (schema.type === 'map') {\n\t\treturn schema.values;\n\t} else if (schema.type === 'any') {\n\t\treturn schema;\n\t} else if (!('type' in schema)) {\n\t\treturn schema[key] ?? null;\n\t}\n\treturn null;\n}\n", "import cuid from 'cuid';\n\nexport interface TimestampProvider {\n\tnow(version: number): string;\n\tupdate(remoteTimestamp: string): void;\n\tzero(version: number): string;\n\tgetWallClockTime(timestamp: string): number;\n}\n\nconst VERSION_BLOCK_LENGTH = 4;\nconst ENCODING_NUMBER_RADIX = 36;\n\nexport function encodeVersion(version: number | string): string {\n\treturn version\n\t\t.toString(ENCODING_NUMBER_RADIX)\n\t\t.padStart(VERSION_BLOCK_LENGTH, '0');\n}\n\nexport function OLD_encodeVersion(version: number | string): string {\n\treturn version.toString().padStart(6, '0');\n}\n\nexport class NaiveTimestampProvider implements TimestampProvider {\n\tcounter = 0;\n\tnow = (version: number | string) => {\n\t\treturn (\n\t\t\tencodeVersion(version) + Date.now().toString() + '-' + this.counter++\n\t\t);\n\t};\n\tupdate = () => {\n\t\tthis.counter = 0;\n\t};\n\tzero = (version: number | string) => {\n\t\treturn encodeVersion(version) + '0' + '-' + this.counter++;\n\t};\n\tgetWallClockTime = (timestamp: string) => {\n\t\treturn parseInt(timestamp.slice(VERSION_BLOCK_LENGTH).split('-')[0], 10);\n\t};\n\n\treset() {\n\t\tthis.counter = 0;\n\t}\n}\n\n// good for tests that require determinism.\nexport class FixedTimestampProvider implements TimestampProvider {\n\ttime = new Date(2025, 2, 19).getTime().toString();\n\tcounter = 0;\n\tnow = (version: number | string) => {\n\t\treturn encodeVersion(version) + this.time + '-' + this.counter++;\n\t};\n\tupdate = () => {};\n\tzero = (version: number | string) => {\n\t\treturn encodeVersion(version) + '0' + '-' + this.counter++;\n\t};\n\tgetWallClockTime = () => 0;\n}\n\nexport class HybridLogicalClockTimestampProvider implements TimestampProvider {\n\tprivate latest: HLCTimestamp = {\n\t\ttime: Date.now(),\n\t\tcounter: 0,\n\t\tnode: generateNodeId(),\n\t};\n\tprivate zeroCounter = 0;\n\n\tnow = (version: string | number) => {\n\t\tthis.latest = getHlcNow(this.latest);\n\t\treturn this.get(version, this.latest);\n\t};\n\t/**\n\t * @deprecated - use now() instead and update to latest format\n\t */\n\tOLD_now = (version: string | number) => {\n\t\tthis.latest = getHlcNow(this.latest);\n\t\treturn OLD_encodeVersion(version) + OLD_serializeHlcTimestamp(this.latest);\n\t};\n\t/** Get the current timer state. Does not increment counter. */\n\ttimerState = () => {\n\t\treturn this.latest;\n\t};\n\tupdate = (remoteTimestamp: string) => {\n\t\t// strip version from remote timestamp\n\t\tconst hlcString = remoteTimestamp.slice(VERSION_BLOCK_LENGTH);\n\t\tthis.latest = updateFromRemote(\n\t\t\tthis.latest,\n\t\t\tdeserializeHlcTimestamp(hlcString),\n\t\t);\n\t};\n\tget = (version: string | number, raw: HLCTimestamp) => {\n\t\treturn encodeVersion(version) + serializeHlcTimestamp(raw);\n\t};\n\tzero = (version: string | number) => {\n\t\treturn (\n\t\t\tencodeVersion(version) +\n\t\t\tserializeHlcTimestamp({\n\t\t\t\ttime: 0,\n\t\t\t\t// to keep zero timestamps unique, we use a counter here as well\n\t\t\t\tcounter: this.zeroCounter++,\n\t\t\t\tnode: this.latest.node,\n\t\t\t})\n\t\t);\n\t};\n\tgetWallClockTime = getWallClockTime;\n}\n\nclass ClockDriftError extends Error {\n\ttype: string;\n\tconstructor(...args: any[]) {\n\t\tsuper();\n\t\tthis.type = 'ClockDriftError';\n\t\tthis.message = ['maximum clock drift exceeded'].concat(args).join(' ');\n\t}\n}\n\nclass OverflowError extends Error {\n\ttype: string;\n\tconstructor() {\n\t\tsuper();\n\t\tthis.type = 'OverflowError';\n\t\tthis.message = 'timestamp counter overflow';\n\t}\n}\n\ninterface HLCTimestamp {\n\ttime: number;\n\tcounter: number;\n\tnode: string;\n}\n\nconst COUNTER_BLOCK_LENGTH = 4;\nconst NODE_BLOCK_LENGTH = 7;\nconst MAX_CLOCK_DRIFT = 60 * 1000;\n// 9 base36 characters should last until the year 5000\n// when encoding a unix MS timestamp\nconst TIME_BLOCK_LENGTH = 9;\n\nfunction generateNodeId() {\n\treturn cuid\n\t\t.slug()\n\t\t.padStart(NODE_BLOCK_LENGTH, '0')\n\t\t.slice(0, NODE_BLOCK_LENGTH);\n}\n\nexport function serializeHlcTimestamp(ts: HLCTimestamp): string {\n\t// string representation of the time\n\tconst dateString = new Date(ts.time)\n\t\t.getTime()\n\t\t.toString(ENCODING_NUMBER_RADIX)\n\t\t.padStart(TIME_BLOCK_LENGTH, '0');\n\t// counter, 336, padded to 4 characters\n\tconst counter = ts.counter\n\t\t.toString(ENCODING_NUMBER_RADIX)\n\t\t.padStart(COUNTER_BLOCK_LENGTH, '0');\n\t// node id padded to 16 characters\n\tconst node = ts.node.padStart(NODE_BLOCK_LENGTH, '0');\n\treturn `${dateString}${counter}${node}`;\n}\n\nfunction getHlcNow(prev: HLCTimestamp): HLCTimestamp {\n\tconst wallTime = Date.now();\n\n\t// pick prev's time if it's later than our local device\n\tconst newWallTime = Math.max(prev.time, wallTime);\n\t// reset counter if wall time changed\n\tconst newCounter = prev.time === newWallTime ? prev.counter + 1 : 0;\n\n\t// check for drift\n\tif (newWallTime - wallTime > MAX_CLOCK_DRIFT) {\n\t\tthrow new ClockDriftError(newWallTime, wallTime, MAX_CLOCK_DRIFT);\n\t}\n\t// check for counter overflow (max is 4 bytes)\n\tif (newCounter > 65535) {\n\t\tthrow new OverflowError();\n\t}\n\n\treturn {\n\t\ttime: newWallTime,\n\t\tcounter: newCounter,\n\t\tnode: prev.node,\n\t};\n}\n\nfunction updateFromRemote(\n\tlocal: HLCTimestamp,\n\tremote: HLCTimestamp,\n): HLCTimestamp {\n\tconst wallTime = Date.now();\n\t// pick remote's time if it's later than our local device\n\tconst newTime = Math.max(wallTime, Math.max(local.time, remote.time));\n\n\tconst maxCounter = Math.max(local.counter, remote.counter);\n\tlet newCounter;\n\t// if all clocks are the same, increment the counter\n\tif (local.time === newTime && remote.time === newTime) {\n\t\tnewCounter = maxCounter + 1;\n\t}\n\t// if local time is the same as new time, increment our local counter\n\telse if (local.time === newTime) {\n\t\tnewCounter = local.counter + 1;\n\t}\n\t// if remote time is the same as new time, increment remote counter\n\telse if (remote.time === newTime) {\n\t\tnewCounter = remote.counter + 1;\n\t}\n\t// otherwise, reset the counter\n\telse {\n\t\tnewCounter = 0;\n\t}\n\n\t// check for drift\n\tif (newTime - wallTime > MAX_CLOCK_DRIFT) {\n\t\tthrow new ClockDriftError(newTime, wallTime, MAX_CLOCK_DRIFT);\n\t}\n\tif (newCounter > 65535) {\n\t\tthrow new OverflowError();\n\t}\n\n\treturn {\n\t\ttime: newTime,\n\t\tcounter: newCounter,\n\t\tnode: local.node,\n\t};\n}\n\nexport function deserializeHlcTimestamp(clock: string): HLCTimestamp {\n\tconst dateString = clock.slice(0, TIME_BLOCK_LENGTH);\n\tconst counter = clock.slice(\n\t\tTIME_BLOCK_LENGTH,\n\t\tTIME_BLOCK_LENGTH + COUNTER_BLOCK_LENGTH,\n\t);\n\tconst node = clock.slice(TIME_BLOCK_LENGTH + COUNTER_BLOCK_LENGTH);\n\tconst time = parseInt(dateString, ENCODING_NUMBER_RADIX);\n\tconst counterNum = parseInt(counter, ENCODING_NUMBER_RADIX);\n\n\tif (isNaN(time) || isNaN(counterNum)) {\n\t\tthrow new Error('invalid clock format');\n\t}\n\n\treturn {\n\t\ttime,\n\t\tcounter: counterNum,\n\t\tnode,\n\t};\n}\n\nfunction removeLeadingZeroes(str: string): string {\n\treturn str.replace(/^0+/, '');\n}\n\n/**\n * Below, converters for old-style timestamps are defined.\n * These are for migrating older clients to the new format.\n */\n\n/**\n * Converts a timestamp from the old format to the new format.\n */\nexport function convertOldHlcTimestamp(ts: string): string {\n\tconst versionBlock = ts.slice(0, 6);\n\t// no jokes please\n\tconst clockBlock = ts.slice(6);\n\tconst deserialized = OLD_deserializeHlcTimestamp(clockBlock);\n\n\t// version was base 10 and now is base 36\n\tconst versionNumber = parseInt(versionBlock, 10);\n\tconst encodedVersion = encodeVersion(versionNumber);\n\treturn encodedVersion + serializeHlcTimestamp(deserialized);\n}\n\nexport function OLD_serializeHlcTimestamp(ts: HLCTimestamp): string {\n\t// ISO string representation of the time\n\tconst dateString = new Date(ts.time).toISOString();\n\t// counter, base16, padded to 4 characters\n\tconst counter = ts.counter.toString(16).toUpperCase().padStart(4, '0');\n\t// node id padded to 16 characters\n\tconst node = ts.node.padStart(16, '0');\n\treturn `${dateString}-${counter}-${node}`;\n}\n\nexport function OLD_deserializeHlcTimestamp(clock: string): HLCTimestamp {\n\t// ISO string representation of the time\n\tconst dateString = clock.slice(0, 24);\n\tconst counter = clock.slice(25, 25 + 4);\n\tconst node = clock.slice(25 + 4 + 1);\n\n\tconst time = new Date(dateString).getTime();\n\tconst counterNum = parseInt(counter, 16);\n\n\tif (isNaN(time) || isNaN(counterNum)) {\n\t\tthrow new Error('invalid clock format');\n\t}\n\n\treturn {\n\t\ttime,\n\t\tcounter: counterNum,\n\t\tnode: node.slice(node.length - 7),\n\t};\n}\n\nexport function getTimestampSchemaVersion(timestamp: string): number {\n\treturn parseInt(timestamp.slice(0, VERSION_BLOCK_LENGTH), 36);\n}\n\nexport function compareTimestampSchemaVersions(a: string, b: string) {\n\treturn getTimestampSchemaVersion(a) - getTimestampSchemaVersion(b);\n}\n\nexport function getWallClockTime(timestamp: string): number {\n\treturn deserializeHlcTimestamp(timestamp.slice(VERSION_BLOCK_LENGTH)).time;\n}\n", "import { AuthorizationKey } from './authz.js';\nimport { ObjectIdentifier } from './oids.js';\nimport { applyPatch, Operation } from './operation.js';\nimport { PatchCreator } from './patch.js';\nimport { isRef } from './refs.js';\nimport { cloneDeep } from './utils.js';\n\nexport function getUndoOperations(\n\toid: ObjectIdentifier,\n\tinitial: any,\n\toperations: Operation[],\n\tgetNow: () => string,\n\tgetSubId?: () => string,\n\tauthz?: AuthorizationKey,\n): Operation[] {\n\tconst patchCreator = new PatchCreator(getNow, getSubId);\n\tif (initial === undefined || initial === null) {\n\t\t// if the initial state is nothing, then the undo is to delete everything.\n\t\t// there's nothing else to worry about!\n\t\treturn [\n\t\t\t{\n\t\t\t\toid,\n\t\t\t\ttimestamp: getNow(),\n\t\t\t\tdata: {\n\t\t\t\t\top: 'delete',\n\t\t\t\t},\n\t\t\t\tauthz,\n\t\t\t},\n\t\t];\n\t}\n\t// otherwise, traverse the operations one by one,\n\t// applying them, and using the prior state to determine\n\t// what the undo operation is.\n\tlet state = cloneDeep(initial);\n\tconst undoOperations: Operation[] = [];\n\tfor (const operation of operations) {\n\t\tconst undo = getUndoOperation(oid, state, operation, patchCreator, authz);\n\t\tundoOperations.unshift(...undo);\n\t\tapplyPatch(state, operation.data);\n\t}\n\treturn undoOperations;\n}\n\nfunction getUndoOperation(\n\toid: ObjectIdentifier,\n\tinitial: any,\n\toperation: Operation,\n\tpatchCreator: PatchCreator,\n\tauthz?: AuthorizationKey,\n): Operation[] {\n\tconst data = operation.data;\n\tswitch (data.op) {\n\t\tcase 'set':\n\t\t\tif (initial[data.name] === undefined) {\n\t\t\t\treturn patchCreator.createRemove(oid, data.name, authz);\n\t\t\t}\n\t\t\treturn patchCreator.createSet(oid, data.name, initial[data.name], authz);\n\t\tcase 'remove':\n\t\t\tif (initial[data.name] === undefined) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\treturn patchCreator.createSet(oid, data.name, initial[data.name], authz);\n\t\tcase 'list-insert':\n\t\t\tif (data.value === undefined && data.values?.length === 0) return [];\n\t\t\treturn patchCreator.createListDelete(\n\t\t\t\toid,\n\t\t\t\tdata.index,\n\t\t\t\tdata.value ? 1 : data.values?.length || 0,\n\t\t\t\tauthz,\n\t\t\t);\n\t\tcase 'list-delete':\n\t\t\treturn patchCreator.createListInsertMany(\n\t\t\t\toid,\n\t\t\t\tdata.index,\n\t\t\t\tinitial.slice(data.index, data.index + data.count),\n\t\t\t\tauthz,\n\t\t\t);\n\t\tcase 'list-move-by-ref':\n\t\t\treturn patchCreator.createListMoveByRef(\n\t\t\t\toid,\n\t\t\t\tdata.value,\n\t\t\t\tfindItemRefIndex(initial, data.value),\n\t\t\t\tauthz,\n\t\t\t);\n\t\tcase 'list-move-by-index':\n\t\t\treturn patchCreator.createListMoveByIndex(oid, data.to, data.from, authz);\n\t\tcase 'delete':\n\t\t\treturn patchCreator.createInitialize(initial, oid, authz, true);\n\t\tcase 'list-push':\n\t\t\treturn patchCreator.createListRemove(oid, data.value, 'last', authz);\n\t\tcase 'list-remove':\n\t\t\tif (data.only === 'last') {\n\t\t\t\tconst index = findItemRefIndex(initial, data.value, 0, 'backward');\n\t\t\t\tif (index === -1) {\n\t\t\t\t\t// if the value isn't in the list, then there's nothing to undo.\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\treturn patchCreator.createListInsert(oid, index, data.value, authz);\n\t\t\t} else if (data.only === 'first') {\n\t\t\t\tconst index = findItemRefIndex(initial, data.value);\n\t\t\t\tif (index === -1) {\n\t\t\t\t\t// if the value isn't in the list, then there's nothing to undo.\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\treturn patchCreator.createListInsert(oid, index, data.value, authz);\n\t\t\t} else {\n\t\t\t\t// find all instances of value and restore them at their\n\t\t\t\t// original index\n\t\t\t\tconst indexesOfValue = [];\n\t\t\t\tlet index = findItemRefIndex(initial, data.value);\n\t\t\t\twhile (index !== -1) {\n\t\t\t\t\tindexesOfValue.push(index);\n\t\t\t\t\tindex = findItemRefIndex(initial, data.value, index + 1);\n\t\t\t\t}\n\t\t\t\treturn indexesOfValue.flatMap((index) =>\n\t\t\t\t\tpatchCreator.createListInsert(oid, index, data.value, authz),\n\t\t\t\t);\n\t\t\t}\n\t\tcase 'list-add':\n\t\t\t// this one is kind of ambiguous. in theory the set may have\n\t\t\t// already included the value and so no change happened. but\n\t\t\t// basically we infer the intent is to remove what was meant\n\t\t\t// to be added by this change.\n\t\t\treturn patchCreator.createListRemove(oid, data.value, 'last', authz);\n\t\tcase 'list-set':\n\t\t\tif (initial[data.index] !== undefined) {\n\t\t\t\treturn patchCreator.createListSet(\n\t\t\t\t\toid,\n\t\t\t\t\tdata.index,\n\t\t\t\t\tinitial[data.index],\n\t\t\t\t\tauthz,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn patchCreator.createListDelete(oid, data.index, 1, authz);\n\t\tcase 'initialize':\n\t\t\treturn patchCreator.createDelete(oid, authz);\n\t\tcase 'touch':\n\t\t\treturn [];\n\t\tdefault:\n\t\t\tthrow new Error(`Cannot undo operation type: ${(data as any).op}`);\n\t}\n}\n\nfunction findItemRefIndex(\n\tlist: any[],\n\titem: any,\n\tfrom: number = 0,\n\tdir: 'forward' | 'backward' = 'forward',\n) {\n\tconst method = dir === 'forward' ? 'findIndex' : 'findLastIndex';\n\t// for object items, attempt to find the matching item by OID.\n\tif (isRef(item)) {\n\t\treturn list[method](\n\t\t\t(i, idx) => isRef(i) && i.id === item.id && idx >= from,\n\t\t);\n\t}\n\treturn list[method]((i, idx) => i === item && idx >= from);\n}\n", "/**\n * This exists since I'm a little anxious about using WeakRef in production\n * and want to be able to roll it back quickly to debug issues. Basically by adding\n * import { WeakRef } from 'FakeWeakRef' to the top of the file, we can switch back\n * to using a simple object reference.\n */\n\nexport class FakeWeakRef<T extends symbol | object> {\n\tconstructor(value: T) {\n\t\tthis.value = value;\n\t}\n\n\tvalue: T;\n\n\tderef(): T | undefined {\n\t\treturn this.value;\n\t}\n}\n", "import { EventSubscriber } from '@verdant-web/common';\n\ntype Undoable = () => Undoable | Promise<Undoable | null> | null;\n\nexport class UndoHistory extends EventSubscriber<{ change: () => void }> {\n\tprivate _undoable: Undoable[] = [];\n\tprivate _undone: Undoable[] = [];\n\n\tget canUndo() {\n\t\treturn this._undoable.length > 0;\n\t}\n\tget canRedo() {\n\t\treturn this._undone.length > 0;\n\t}\n\n\tget undoLength() {\n\t\treturn this._undoable.length;\n\t}\n\tget redoLength() {\n\t\treturn this._undone.length;\n\t}\n\n\tundo = async () => {\n\t\tconst next = this._undoable.pop();\n\t\tif (next) {\n\t\t\tconst redo = await next();\n\t\t\tif (redo) this._undone.push(redo);\n\t\t\tthis.emit('change');\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t};\n\n\tredo = async () => {\n\t\tconst next = this._undone.pop();\n\t\tif (next) {\n\t\t\tconst undo = await next();\n\t\t\tif (undo) this._undoable.push(undo);\n\t\t\tthis.emit('change');\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t};\n\n\taddUndo = (undoPoint: Undoable) => {\n\t\tthis._undoable.push(undoPoint);\n\t\tthis._undone = [];\n\t\tthis.emit('change');\n\t};\n\n\taddRedo = (redoPoint: Undoable) => {\n\t\tthis._undone.push(redoPoint);\n\t\tthis.emit('change');\n\t};\n\n\tclear = () => {\n\t\tthis._undoable = [];\n\t\tthis._undone = [];\n\t\tthis.emit('change');\n\t};\n}\n", "export type VerdantLogger = (\n\tlevel: 'debug' | 'info' | 'warn' | 'error' | 'critical',\n\t...args: any[]\n) => void;\n\nexport const noLogger = () => {};\n\nexport const makeLogger =\n\t(prefix?: string): VerdantLogger =>\n\t(level, ...args) => {\n\t\tif (level === 'critical') {\n\t\t\targs.unshift('[CRITICAL]');\n\t\t}\n\t\tif (prefix) {\n\t\t\targs.unshift(`[${prefix}]`);\n\t\t}\n\t\tif (level === 'critical') {\n\t\t\tconsole.error(...args);\n\t\t} else {\n\t\t\tconsole[level](...args);\n\t\t}\n\t};\n\nexport function debugLogger(prefix?: string): VerdantLogger {\n\tif (!localStorage.getItem('DEBUG')) {\n\t\treturn noLogger;\n\t}\n\treturn makeLogger(prefix);\n}\n", "export class Disposable {\n\tprivate _disposes: (() => void | Promise<void>)[] = [];\n\tprotected disposed = false;\n\n\tdispose = async () => {\n\t\tthis.disposed = true;\n\t\tawait Promise.all(\n\t\t\tthis._disposes.map(async (dispose) => {\n\t\t\t\ttry {\n\t\t\t\t\tawait dispose();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconsole.error('Error disposing', err);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t\tthis._disposes = [];\n\t};\n\n\tcompose = (disposable: { dispose: () => void | Promise<void> }) =>\n\t\tthis.addDispose(disposable.dispose.bind(disposable));\n\n\tprotected addDispose = (dispose: () => void | Promise<void>) => {\n\t\tthis._disposes.push(dispose);\n\t};\n}\n", "import { roughSizeOfObject } from '@verdant-web/common';\nimport { Context } from '../../internal.js';\n\nexport const globalIDB =\n\ttypeof window !== 'undefined' ? window.indexedDB : (undefined as any);\n\nexport function isAbortError(err: unknown) {\n\treturn err instanceof Error && err.name === 'AbortError';\n}\n\nexport function storeRequestPromise<T>(request: IDBRequest<T>) {\n\treturn new Promise<T>((resolve, reject) => {\n\t\trequest.onsuccess = () => {\n\t\t\tresolve(request.result);\n\t\t};\n\t\trequest.onerror = () => {\n\t\t\tif (request.error && isAbortError(request.error)) {\n\t\t\t\t// TODO: is this the right thing to do?\n\t\t\t\tresolve(request.result);\n\t\t\t} else {\n\t\t\t\treject(request.error);\n\t\t\t}\n\t\t};\n\t});\n}\n\nexport function cursorIterator<T>(\n\trequest: IDBRequest<IDBCursorWithValue | null>,\n\tcallback: (value: T | null) => boolean,\n) {\n\treturn new Promise<void>((resolve, reject) => {\n\t\trequest.onsuccess = () => {\n\t\t\tconst cursor = request.result;\n\t\t\tif (cursor) {\n\t\t\t\tif (callback(cursor.value)) {\n\t\t\t\t\tcursor.continue();\n\t\t\t\t} else {\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t};\n\t\trequest.onerror = () => {\n\t\t\tif (request.error && isAbortError(request.error)) {\n\t\t\t\tresolve();\n\t\t\t} else {\n\t\t\t\treject(request.error);\n\t\t\t}\n\t\t};\n\t});\n}\n\nexport function getSizeOfObjectStore(\n\tdatabase: IDBDatabase,\n\tstoreName: string,\n): Promise<{ count: number; size: number }> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst tx = database.transaction([storeName], 'readonly');\n\t\tconst store = tx.objectStore(storeName);\n\t\tconst cursorReq = store.openCursor();\n\t\tlet count = 0;\n\t\tlet size = 0;\n\t\tcursorReq.onsuccess = function (e) {\n\t\t\tconst cursor = cursorReq.result;\n\t\t\tif (cursor) {\n\t\t\t\tcount++;\n\t\t\t\tsize = size + roughSizeOfObject(cursor.value);\n\t\t\t\tcursor.continue();\n\t\t\t}\n\t\t};\n\t\tcursorReq.onerror = function (e) {\n\t\t\tif (cursorReq.error && isAbortError(cursorReq.error)) {\n\t\t\t\tresolve({\n\t\t\t\t\tcount: count,\n\t\t\t\t\tsize: size,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\treject(cursorReq.error);\n\t\t\t}\n\t\t};\n\t\ttx.oncomplete = function (e) {\n\t\t\tresolve({\n\t\t\t\tcount: count,\n\t\t\t\tsize: size,\n\t\t\t});\n\t\t};\n\t\ttx.onabort = function (e) {\n\t\t\treject(e);\n\t\t};\n\t\ttx.onerror = function (e) {\n\t\t\treject(e);\n\t\t};\n\t});\n}\n\nexport async function getSizesOfAllObjectStores(\n\tdatabase: IDBDatabase,\n): Promise<{ [storeName: string]: { count: number; size: number } }> {\n\tconst storeNames = Array.from(database.objectStoreNames);\n\tconst promises = storeNames.map(async (storeName) => {\n\t\tconst result = await getSizeOfObjectStore(database, storeName);\n\t\treturn { [storeName]: result };\n\t});\n\tconst results = await Promise.all(promises);\n\treturn results.reduce((acc, result_1) => {\n\t\treturn { ...acc, ...result_1 };\n\t}, {});\n}\n\nexport function getAllFromObjectStores(db: IDBDatabase, stores: string[]) {\n\tconst transaction = db.transaction(stores, 'readonly');\n\tconst promises = stores.map((store) => {\n\t\tconst objectStore = transaction.objectStore(store);\n\t\treturn storeRequestPromise(objectStore.getAll());\n\t});\n\treturn Promise.all(promises);\n}\n\nexport async function closeDatabase(db: IDBDatabase) {\n\tdb.close();\n\t// wait for microtask queue to clear\n\tawait new Promise<void>((resolve) => {\n\t\tresolve();\n\t});\n\tawait new Promise<void>((resolve) => {\n\t\tresolve();\n\t});\n}\n\nexport async function deleteAllDatabases(\n\tnamespace: string,\n\tenvironment: Context['environment'],\n) {\n\tconst req1 = environment.indexedDB.deleteDatabase(\n\t\t[namespace, 'meta'].join('_'),\n\t);\n\tconst req2 = environment.indexedDB.deleteDatabase(\n\t\t[namespace, 'collections'].join('_'),\n\t);\n\tawait Promise.all([\n\t\tnew Promise((resolve, reject) => {\n\t\t\treq1.onsuccess = resolve;\n\t\t\treq1.onerror = reject;\n\t\t}),\n\t\tnew Promise((resolve, reject) => {\n\t\t\treq2.onsuccess = resolve;\n\t\t\treq2.onerror = reject;\n\t\t}),\n\t]);\n\t// reload the page to reset any existing connections\n\tenvironment.location.reload();\n}\n\nexport function deleteDatabase(name: string, indexedDB = window.indexedDB) {\n\treturn storeRequestPromise(indexedDB.deleteDatabase(name));\n}\n\nexport async function getAllDatabaseNamesAndVersions(\n\tindexedDB: IDBFactory = window.indexedDB,\n) {\n\treturn indexedDB.databases();\n}\n\nexport function createAbortableTransaction(\n\tdb: IDBDatabase,\n\tstoreNames: string[],\n\tmode: 'readonly' | 'readwrite',\n\tabortSignal?: AbortSignal,\n\tlog?: (...args: any[]) => void,\n) {\n\ttry {\n\t\tconst tx = db.transaction(storeNames, mode);\n\t\tif (abortSignal) {\n\t\t\tconst abort = () => {\n\t\t\t\tlog?.('debug', 'aborting transaction');\n\t\t\t\ttry {\n\t\t\t\t\ttx.abort();\n\t\t\t\t\t(tx as any).__aborted = true;\n\t\t\t\t} catch (e) {\n\t\t\t\t\tlog?.('debug', 'aborting transaction failed', e);\n\t\t\t\t}\n\t\t\t};\n\t\t\tabortSignal.addEventListener('abort', abort);\n\t\t\ttx.addEventListener('error', () => {\n\t\t\t\tabortSignal.removeEventListener('abort', abort);\n\t\t\t});\n\t\t\ttx.addEventListener('complete', () => {\n\t\t\t\tabortSignal.removeEventListener('abort', abort);\n\t\t\t});\n\t\t}\n\t\treturn tx;\n\t} catch (err) {\n\t\tif (err instanceof Error && err.name === 'InvalidStateError') {\n\t\t\t// database is probably closing. it's ok, what can you do?\n\t\t\tlog?.('warn', 'Failed to create transaction, database is closing');\n\t\t\t// mock a Transaction so code can continue,\n\t\t\t// but doesn't do anything.\n\t\t\treturn {\n\t\t\t\tabort: () => {},\n\t\t\t\taddEventListener: () => {},\n\t\t\t\tobjectStore: () => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tadd: () => {},\n\t\t\t\t\t\tput: () => {},\n\t\t\t\t\t\tget: () => {},\n\t\t\t\t\t\tgetAll: () => {},\n\t\t\t\t\t\tdelete: () => {},\n\t\t\t\t\t\tclear: () => {},\n\t\t\t\t\t\topenCursor: () => {\n\t\t\t\t\t\t\tconst req = {\n\t\t\t\t\t\t\t\tonsuccess: () => {},\n\t\t\t\t\t\t\t\tonerror: (_: any) => {},\n\t\t\t\t\t\t\t\tresult: null,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\t\treq.onerror({} as any);\n\t\t\t\t\t\t\t}, 0);\n\t\t\t\t\t\t\treturn req;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tindex: () => {\n\t\t\t\t\t\t\tthrow new Error('Transaction is not active');\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\toncomplete: null,\n\t\t\t\tonerror: null,\n\t\t\t\tonabort: null,\n\t\t\t\terror: new Error('Transaction is not active') as any,\n\t\t\t\tcommit: () => {},\n\t\t\t\tdb,\n\t\t\t\tdispatchEvent: () => false,\n\t\t\t\tremoveEventListener: () => {},\n\t\t\t\tdurability: 'default',\n\t\t\t\tmode: 'readonly',\n\t\t\t\tobjectStoreNames: storeNames as any,\n\t\t\t\t__aborted: true,\n\t\t\t} as unknown as IDBTransaction;\n\t\t} else {\n\t\t\tthrow err;\n\t\t}\n\t}\n}\n\nexport function isTransactionAborted(tx: IDBTransaction) {\n\treturn (tx as any).__aborted;\n}\n\n/**\n * Deletes any existing database with name `toName` and\n * copies the index structure and all data\n * from `from` to a new database.\n *\n * Does NOT run Verdant migrations. Use to copy existing\n * data as-is.\n */\nexport async function overwriteDatabase(\n\tfrom: IDBDatabase,\n\ttoName: string,\n\tctx: Pick<Context, 'log'>,\n\tindexedDB = window.indexedDB,\n) {\n\tconst databases = await getAllDatabaseNamesAndVersions(indexedDB);\n\tif (databases.some((d) => d.name === toName)) {\n\t\tawait deleteDatabase(toName, indexedDB);\n\t\tctx.log('debug', 'Deleted existing database', toName);\n\t}\n\n\tconst to = await new Promise<IDBDatabase>((resolve, reject) => {\n\t\tctx.log(\n\t\t\t'debug',\n\t\t\t'Copying to database',\n\t\t\ttoName,\n\t\t\t'at',\n\t\t\tfrom.version,\n\t\t\t'from',\n\t\t\tfrom.name,\n\t\t);\n\t\tconst openRequest = indexedDB.open(toName, from.version);\n\t\topenRequest.onupgradeneeded = () => {\n\t\t\tctx.log(\n\t\t\t\t'debug',\n\t\t\t\t'Upgrading database',\n\t\t\t\ttoName,\n\t\t\t\t'to version',\n\t\t\t\tfrom.version,\n\t\t\t);\n\t\t\t// copy all indexes from original\n\t\t\tconst original = from;\n\t\t\tconst upgradeTx = openRequest.transaction;\n\t\t\tif (!upgradeTx) {\n\t\t\t\tthrow new Error('No transaction');\n\t\t\t}\n\t\t\tfor (const storeName of Array.from(original.objectStoreNames)) {\n\t\t\t\tctx.log('debug', 'Copying object store', storeName);\n\t\t\t\tconst originalObjectStore = original\n\t\t\t\t\t.transaction(storeName)\n\t\t\t\t\t.objectStore(storeName);\n\t\t\t\t// create object store\n\t\t\t\tupgradeTx.db.createObjectStore(storeName, {\n\t\t\t\t\tkeyPath: originalObjectStore.keyPath,\n\t\t\t\t\tautoIncrement: originalObjectStore.autoIncrement,\n\t\t\t\t});\n\t\t\t\tconst store = upgradeTx.objectStore(storeName);\n\t\t\t\tconst originalStore = original\n\t\t\t\t\t.transaction(storeName)\n\t\t\t\t\t.objectStore(storeName);\n\t\t\t\tfor (const index of Array.from(originalStore.indexNames)) {\n\t\t\t\t\tconst originalIndex = originalStore.index(index);\n\t\t\t\t\tctx.log('debug', 'Copying index', index);\n\t\t\t\t\tstore.createIndex(index, originalIndex.keyPath, {\n\t\t\t\t\t\tunique: originalIndex.unique,\n\t\t\t\t\t\tmultiEntry: originalIndex.multiEntry,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\topenRequest.onsuccess = () => {\n\t\t\tctx.log('debug', 'Opened reset database', toName);\n\t\t\tresolve(openRequest.result);\n\t\t};\n\t\topenRequest.onerror = () =>\n\t\t\treject(openRequest.error ?? new Error('Unknown database upgrade error'));\n\t});\n\n\t// only copy data to new database if there are object stores to\n\t// copy to\n\tif (to.objectStoreNames.length > 0) {\n\t\tconst records = await getAllFromObjectStores(\n\t\t\tfrom,\n\t\t\tArray.from(from.objectStoreNames),\n\t\t);\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tconst writeTx = to.transaction(\n\t\t\t\tArray.from(to.objectStoreNames),\n\t\t\t\t'readwrite',\n\t\t\t);\n\t\t\tfor (let i = 0; i < records.length; i++) {\n\t\t\t\tconst store = writeTx.objectStore(from.objectStoreNames[i]);\n\t\t\t\tfor (const record of records[i]) {\n\t\t\t\t\tstore.add(record);\n\t\t\t\t}\n\t\t\t}\n\t\t\twriteTx.oncomplete = () => resolve();\n\t\t\twriteTx.onerror = (ev) => {\n\t\t\t\tconst err =\n\t\t\t\t\twriteTx.error ??\n\t\t\t\t\t(ev.target as any).transaction?.error ??\n\t\t\t\t\tnew Error('Unknown error');\n\t\t\t\tctx.log('critical', 'Error copying data', err);\n\t\t\t\treject(err);\n\t\t\t};\n\t\t});\n\t}\n\n\tawait closeDatabase(to);\n}\n\nexport function openDatabase(\n\tname: string,\n\texpectedVersion: number,\n\tindexedDB: IDBFactory = window.indexedDB,\n) {\n\treturn new Promise<IDBDatabase>((resolve, reject) => {\n\t\tconst req = indexedDB.open(name, expectedVersion);\n\t\treq.onsuccess = () => {\n\t\t\tif (req.result.version !== expectedVersion) {\n\t\t\t\treq.result.close();\n\t\t\t\treject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t`Migration error: opened database version ${req.result.version} but expected version ${expectedVersion} for database ${name}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve(req.result);\n\t\t};\n\t\treq.onerror = () => {\n\t\t\treject(req.error);\n\t\t};\n\t\treq.onblocked = () => {\n\t\t\treject(new Error('Database blocked'));\n\t\t};\n\t\treq.onupgradeneeded = (event) => {\n\t\t\tconst db = req.result;\n\t\t\tif (db.version !== expectedVersion) {\n\t\t\t\tdb.close();\n\t\t\t\treject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t`Migration error: database version changed unexpectedly when reading current data. Expected ${expectedVersion}, got ${db.version}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\t});\n}\n\nexport function getMetadataDbName(namespace: string) {\n\treturn [namespace, 'meta'].join('_');\n}\n\nexport function getDocumentDbName(namespace: string) {\n\treturn [namespace, 'collections'].join('_');\n}\n\nexport function getNamespaceFromDatabaseInfo(info: IDBDatabaseInfo) {\n\treturn info.name?.split('_')[0];\n}\n", "import { Context } from '../../context/context.js';\nimport { Disposable } from '../../utils/Disposable.js';\nimport {\n\tcreateAbortableTransaction,\n\tisAbortError,\n\tisTransactionAborted,\n\tstoreRequestPromise,\n} from './util.js';\n\nexport class IdbService extends Disposable {\n\tprotected log?: Context['log'];\n\tprivate globalAbortController;\n\n\tconstructor(\n\t\tprotected db: IDBDatabase,\n\t\tprotected readonly ctx: Pick<Context, 'log' | 'environment'>,\n\t) {\n\t\tsuper();\n\t\tconst abortController = new AbortController();\n\t\tthis.globalAbortController = abortController;\n\t\t// FIXME: replace with event? I can't get this to work.\n\t\t// this.addDispose(abort);\n\t\tthis.db.addEventListener('versionchange', this.onVersionChange);\n\t\tthis.addDispose(() => {\n\t\t\tthis.db.removeEventListener('versionchange', this.onVersionChange);\n\t\t});\n\t}\n\n\tcreateTransaction = (\n\t\tstoreNames: string[],\n\t\topts?: {\n\t\t\tmode?: 'readonly' | 'readwrite';\n\t\t\tabort?: AbortSignal;\n\t\t},\n\t) => {\n\t\ttry {\n\t\t\tif (this.globalAbortController.signal.aborted) {\n\t\t\t\tthrow new Error('Global abort signal is already aborted');\n\t\t\t}\n\t\t\tconst tx = createAbortableTransaction(\n\t\t\t\tthis.db,\n\t\t\t\tstoreNames,\n\t\t\t\topts?.mode || 'readonly',\n\t\t\t\topts?.abort,\n\t\t\t\tthis.log,\n\t\t\t);\n\t\t\tthis.globalAbortController.signal.addEventListener('abort', tx.abort);\n\t\t\ttx.addEventListener('complete', () => {\n\t\t\t\tthis.globalAbortController.signal.removeEventListener(\n\t\t\t\t\t'abort',\n\t\t\t\t\ttx.abort,\n\t\t\t\t);\n\t\t\t});\n\t\t\ttx.addEventListener('error', () => {\n\t\t\t\tthis.globalAbortController.signal.removeEventListener(\n\t\t\t\t\t'abort',\n\t\t\t\t\ttx.abort,\n\t\t\t\t);\n\t\t\t});\n\t\t\treturn tx;\n\t\t} catch (err) {\n\t\t\tthis.log?.(\n\t\t\t\t'error',\n\t\t\t\t'Failed to create abortable transaction for store names',\n\t\t\t\tstoreNames,\n\t\t\t\terr,\n\t\t\t);\n\t\t\tthrow err;\n\t\t}\n\t};\n\n\trun = async <T = any>(\n\t\tstoreName: string,\n\t\tgetRequest: (store: IDBObjectStore) => IDBRequest<T>,\n\t\topts?: {\n\t\t\tmode?: 'readonly' | 'readwrite';\n\t\t\ttransaction?: IDBTransaction;\n\t\t\tabort?: AbortSignal;\n\t\t},\n\t): Promise<T> => {\n\t\tif (this.disposed || opts?.transaction?.error)\n\t\t\treturn Promise.resolve(undefined as any);\n\t\tconst tx = opts?.transaction || this.createTransaction([storeName], opts);\n\t\tif (isTransactionAborted(tx)) {\n\t\t\treturn Promise.resolve(undefined as any);\n\t\t}\n\t\tconst store = tx.objectStore(storeName);\n\t\tconst request = getRequest(store);\n\t\treturn storeRequestPromise<T>(request);\n\t};\n\n\trunAll = async <T>(\n\t\tstoreName: string,\n\t\tgetRequests: (store: IDBObjectStore) => IDBRequest<T>[],\n\t\topts?: {\n\t\t\tmode?: 'readonly' | 'readwrite';\n\t\t\ttransaction?: IDBTransaction;\n\t\t\tabort?: AbortSignal;\n\t\t},\n\t): Promise<T[]> => {\n\t\tif (this.disposed || opts?.transaction?.error) return Promise.resolve([]);\n\t\tif (opts?.transaction && isTransactionAborted(opts.transaction)) {\n\t\t\treturn Promise.resolve([]);\n\t\t}\n\t\tconst tx = opts?.transaction || this.createTransaction([storeName], opts);\n\t\tconst store = tx.objectStore(storeName);\n\t\tconst requests = getRequests(store);\n\t\treturn Promise.all(requests.map(storeRequestPromise));\n\t};\n\n\titerate = async <T>(\n\t\tstoreName: string,\n\t\tgetRequest: (\n\t\t\tstore: IDBObjectStore,\n\t\t) =>\n\t\t\t| IDBRequest<IDBCursorWithValue | null>\n\t\t\t| IDBRequest<IDBCursorWithValue | null>[],\n\t\titerator: (\n\t\t\tvalue: T,\n\t\t\tstore: IDBObjectStore,\n\t\t\tcursor: IDBCursorWithValue,\n\t\t) => boolean | void,\n\t\topts?: {\n\t\t\tmode?: 'readonly' | 'readwrite';\n\t\t\ttransaction?: IDBTransaction;\n\t\t\tabort?: AbortSignal;\n\t\t},\n\t): Promise<void> => {\n\t\tconst tx = opts?.transaction || this.createTransaction([storeName], opts);\n\t\tif (isTransactionAborted(tx)) {\n\t\t\treturn;\n\t\t}\n\t\tconst store = tx.objectStore(storeName);\n\t\tconst request = getRequest(store);\n\t\tif (Array.isArray(request)) {\n\t\t\treturn Promise.all(\n\t\t\t\trequest.map((req) => {\n\t\t\t\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\t\t\t\treq.onsuccess = () => {\n\t\t\t\t\t\t\tconst cursor = req.result;\n\t\t\t\t\t\t\tif (cursor) {\n\t\t\t\t\t\t\t\tconst stop = iterator(cursor.value, store, cursor);\n\t\t\t\t\t\t\t\tif (stop) {\n\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcursor.continue();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\treq.onerror = () => {\n\t\t\t\t\t\t\tif (req.error && isAbortError(req.error)) {\n\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treject(req.error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t}),\n\t\t\t).then(() => undefined);\n\t\t}\n\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\trequest.onsuccess = () => {\n\t\t\t\tconst cursor = request.result as IDBCursorWithValue | null;\n\t\t\t\tif (cursor) {\n\t\t\t\t\tconst stop = iterator(cursor.value, store, cursor);\n\t\t\t\t\tif (stop) {\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcursor.continue();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\t\t\trequest.onerror = () => {\n\t\t\t\tif (request.error && isAbortError(request.error)) {\n\t\t\t\t\tresolve();\n\t\t\t\t} else {\n\t\t\t\t\treject(request.error);\n\t\t\t\t}\n\t\t\t};\n\t\t});\n\t};\n\n\tclear = (storeName: string, transaction?: IDBTransaction) => {\n\t\treturn this.run<undefined>(storeName, (store) => store.clear(), {\n\t\t\tmode: 'readwrite',\n\t\t\ttransaction,\n\t\t});\n\t};\n\n\tprivate onVersionChange = (ev: IDBVersionChangeEvent) => {\n\t\tthis.log?.(\n\t\t\t'warn',\n\t\t\t`Another tab has requested a version change for ${this.db.name}`,\n\t\t);\n\t\tthis.db.close();\n\t\tif (typeof window !== 'undefined') {\n\t\t\ttry {\n\t\t\t\tthis.ctx.environment.location.reload();\n\t\t\t} catch (err) {\n\t\t\t\tthis.log?.('error', 'Failed to reload the page', err);\n\t\t\t}\n\t\t}\n\t};\n}\n", "import { FileData } from '@verdant-web/common';\nimport { Context } from '../../../internal.js';\nimport {\n\tAbstractTransaction,\n\tPersistedFileData,\n\tPersistenceFileDb,\n} from '../../interfaces.js';\nimport { IdbService } from '../IdbService.js';\nimport { getAllFromObjectStores, getSizeOfObjectStore } from '../util.js';\n\n/**\n * When stored in IDB, replace the file blob with an array buffer\n * since it's more compatible, and replace remote boolean with\n * a string since IDB doesn't support boolean indexes.\n */\nexport interface StoredFileData extends Omit<FileData, 'remote' | 'file'> {\n\tremote: 'true' | 'false';\n\tbuffer?: ArrayBuffer;\n\tdeletedAt: number | null;\n\ttimestamp?: string;\n}\n\nexport class IdbPersistenceFileDb\n\textends IdbService\n\timplements PersistenceFileDb\n{\n\tadd = async (file: FileData): Promise<void> => {\n\t\tlet buffer = file.file ? await fileToArrayBuffer(file.file) : undefined;\n\n\t\tawait this.run(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store.put({\n\t\t\t\t\tid: file.id,\n\t\t\t\t\t// IDB doesn't support boolean indexes\n\t\t\t\t\tremote: file.remote ? 'true' : 'false',\n\t\t\t\t\tdeletedAt: null,\n\t\t\t\t\tname: file.name,\n\t\t\t\t\ttype: file.type,\n\t\t\t\t\turl: file.url,\n\t\t\t\t\tbuffer,\n\t\t\t\t\ttimestamp: file.timestamp,\n\t\t\t\t} satisfies StoredFileData);\n\t\t\t},\n\t\t\t{\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t);\n\t};\n\tmarkUploaded = async (id: string): Promise<void> => {\n\t\tif (this.disposed) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst current = await this.getFileRaw(id);\n\n\t\tif (!current) {\n\t\t\tthis.ctx.log('error', 'Tried to mark unknown file as uploaded', id);\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.run(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store.put({\n\t\t\t\t\t...current,\n\t\t\t\t\tremote: 'true',\n\t\t\t\t} as StoredFileData);\n\t\t\t},\n\t\t\t{\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t);\n\t};\n\tget = async (fileId: string): Promise<PersistedFileData | null> => {\n\t\tconst raw = await this.getFileRaw(fileId);\n\t\tif (!raw) {\n\t\t\treturn null;\n\t\t}\n\t\treturn this.hydrateFileData(raw);\n\t};\n\tdelete = (fileId: string): Promise<void> => {\n\t\treturn this.run<undefined>(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store.delete(fileId);\n\t\t\t},\n\t\t\t{\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t);\n\t};\n\tmarkPendingDelete = async (fileId: string): Promise<void> => {\n\t\tconst current = await this.getFileRaw(fileId);\n\n\t\tif (!current) {\n\t\t\tthrow new Error('File is not in local database');\n\t\t}\n\n\t\tawait this.run(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store.put({\n\t\t\t\t\t...current,\n\t\t\t\t\tdeletedAt: Date.now(),\n\t\t\t\t} as StoredFileData);\n\t\t\t},\n\t\t\t{\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t);\n\t};\n\tlistUnsynced = async (): Promise<PersistedFileData[]> => {\n\t\tconst raw = await this.run<StoredFileData[]>(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store.index('remote').getAll('false');\n\t\t\t},\n\t\t\t{ mode: 'readonly' },\n\t\t);\n\t\treturn raw?.map(this.hydrateFileData) ?? [];\n\t};\n\tresetSyncedStatusSince = async (since: string | null): Promise<void> => {\n\t\tconst tx: IDBTransaction = this.createTransaction(['files'], {\n\t\t\tmode: 'readwrite',\n\t\t});\n\t\tconst raw = await this.run<StoredFileData[]>(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store.index('remote').getAll('true');\n\t\t\t},\n\t\t\t{ transaction: tx },\n\t\t);\n\n\t\tconst filtered = raw.filter(\n\t\t\t(file) => !file.timestamp || !since || file.timestamp > since,\n\t\t);\n\n\t\tawait Promise.all(\n\t\t\tfiltered.map((file) => {\n\t\t\t\treturn this.run(\n\t\t\t\t\t'files',\n\t\t\t\t\t(store) => {\n\t\t\t\t\t\treturn store.put({\n\t\t\t\t\t\t\t...file,\n\t\t\t\t\t\t\tremote: 'false',\n\t\t\t\t\t\t} as StoredFileData);\n\t\t\t\t\t},\n\t\t\t\t\t{ transaction: tx },\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\t};\n\titerateOverPendingDelete = (\n\t\titerator: (file: PersistedFileData, store: IDBObjectStore) => void,\n\t): Promise<void> => {\n\t\treturn this.iterate<StoredFileData>(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store\n\t\t\t\t\t.index('deletedAt')\n\t\t\t\t\t.openCursor(IDBKeyRange.lowerBound(0, true));\n\t\t\t},\n\t\t\t(value, store) => {\n\t\t\t\titerator(this.hydrateFileData(value), store);\n\t\t\t},\n\t\t\t{\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t);\n\t};\n\tgetAll = async (options?: {\n\t\ttransaction?: AbstractTransaction;\n\t}): Promise<PersistedFileData[]> => {\n\t\tconst [files] = await getAllFromObjectStores(this.db, ['files']);\n\t\treturn files.map(this.hydrateFileData);\n\t};\n\tstats = async (): Promise<{ size: { count: number; size: number } }> => {\n\t\treturn {\n\t\t\tsize: await getSizeOfObjectStore(this.db, 'files'),\n\t\t};\n\t};\n\tloadFileContents = async (file: FileData, ctx: Context): Promise<Blob> => {\n\t\tif (file.file) return file.file;\n\t\tif (file.localPath) {\n\t\t\tthrow new Error('Local file paths are not supported in browser');\n\t\t}\n\t\tif (file.url) {\n\t\t\tconst response = await ctx.environment.fetch(file.url);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Failed to download file ${file.url}: ${response.statusText}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn response.blob();\n\t\t}\n\t\tthrow new Error('File is missing url, file, and localPath');\n\t};\n\n\tprivate hydrateFileData = (raw: StoredFileData): PersistedFileData => {\n\t\t(raw as any).remote = raw.remote === 'true';\n\t\tconst buffer = raw.buffer;\n\t\tdelete raw.buffer;\n\t\t(raw as unknown as FileData).file = buffer\n\t\t\t? arrayBufferToBlob(buffer, raw.type, raw.name)\n\t\t\t: undefined;\n\t\treturn raw as unknown as PersistedFileData;\n\t};\n\n\tprivate getFileRaw = async (\n\t\tid: string,\n\t\t{ transaction }: { transaction?: AbstractTransaction } = {},\n\t): Promise<StoredFileData | undefined> => {\n\t\tif (this.disposed) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst raw = await this.run<StoredFileData>(\n\t\t\t'files',\n\t\t\t(store) => {\n\t\t\t\treturn store.get(id);\n\t\t\t},\n\t\t\t{ mode: 'readonly', transaction: transaction as IDBTransaction },\n\t\t);\n\t\tif (!raw) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn raw;\n\t};\n}\n\nexport function arrayBufferToBlob(\n\tbuffer: ArrayBuffer,\n\ttype: string,\n\tname?: string,\n) {\n\treturn new File([new Blob([buffer], { type })], name ?? 'blob', {\n\t\ttype,\n\t});\n}\n\nfunction fileToArrayBuffer(file: File | Blob): Promise<ArrayBuffer> {\n\t// special case for testing...\n\tif ('__testReadBuffer' in file) {\n\t\treturn Promise.resolve<any>(file.__testReadBuffer);\n\t}\n\treturn new Promise<ArrayBuffer>((resolve, reject) => {\n\t\tconst reader = new FileReader();\n\t\treader.onload = () => {\n\t\t\tresolve(reader.result as ArrayBuffer);\n\t\t};\n\t\treader.onerror = reject;\n\t\treader.readAsArrayBuffer(file);\n\t});\n}\n", "import {\n\tcreateCompoundIndexValue,\n\tcreateLowerBoundIndexValue,\n\tcreateUpperBoundIndexValue,\n\tDocumentBaseline,\n\tgetLegacyDotOidSubIdRange,\n\tgetOidRoot,\n\tgetOidSubIdRange,\n\tObjectIdentifier,\n} from '@verdant-web/common';\nimport { ContextWithoutPersistence } from '../../../context/context.js';\nimport {\n\tAbstractTransaction,\n\tAckInfo,\n\tClientOperation,\n\tCommonQueryOptions,\n\tIterator,\n\tLocalReplicaInfo,\n\tPersistenceMetadataDb,\n} from '../../interfaces.js';\nimport { IdbService } from '../IdbService.js';\nimport { closeDatabase, getSizeOfObjectStore } from '../util.js';\n\nexport type StoredClientOperation = ClientOperation & {\n\t/** This acts as the primary key */\n\toid_timestamp: string;\n\tl_t: string;\n\td_t: string;\n};\n\nexport type StoredSchema = {\n\ttype: 'schema';\n\tschema: string;\n};\n\nexport class IdbMetadataDb\n\textends IdbService\n\timplements PersistenceMetadataDb<IDBTransaction>\n{\n\tconstructor(db: IDBDatabase, ctx: ContextWithoutPersistence) {\n\t\tsuper(db, ctx);\n\t\tthis.addDispose(() => {\n\t\t\tthis.ctx.log('info', `Closing metadata DB for`, ctx.namespace);\n\t\t\treturn closeDatabase(db);\n\t\t});\n\t}\n\n\ttransaction = async <T>(\n\t\topts: {\n\t\t\tmode?: 'readwrite' | 'readonly';\n\t\t\tstoreNames: string[];\n\t\t\tabort?: AbortSignal;\n\t\t},\n\t\tprocedure: (tx: IDBTransaction) => Promise<T>,\n\t) => {\n\t\tconst tx = this.createTransaction(opts.storeNames, {\n\t\t\tmode: opts.mode,\n\t\t\tabort: opts.abort,\n\t\t});\n\t\tconst result = await procedure(tx);\n\t\treturn result;\n\t};\n\n\tgetAckInfo = async (): Promise<AckInfo> => {\n\t\tconst result = await this.run<AckInfo>('info', (store) => store.get('ack'));\n\t\tif (result) {\n\t\t\treturn result;\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tglobalAckTimestamp: null,\n\t\t\t};\n\t\t}\n\t};\n\n\tsetGlobalAck = async (ack: string): Promise<void> => {\n\t\tawait this.run(\n\t\t\t'info',\n\t\t\t(store) => store.put({ type: 'ack', globalAckTimestamp: ack }),\n\t\t\t{ mode: 'readwrite' },\n\t\t);\n\t};\n\n\tgetLocalReplica = async (\n\t\topts?: CommonQueryOptions,\n\t): Promise<LocalReplicaInfo | undefined> => {\n\t\treturn this.run<LocalReplicaInfo | undefined>(\n\t\t\t'info',\n\t\t\t(store) => store.get('localReplicaInfo'),\n\t\t\topts,\n\t\t);\n\t};\n\n\tupdateLocalReplica = async (\n\t\tdata: LocalReplicaInfo,\n\t\topts?: CommonQueryOptions,\n\t): Promise<void> => {\n\t\ttry {\n\t\t\tawait this.run(\n\t\t\t\t'info',\n\t\t\t\t(store) =>\n\t\t\t\t\tstore.put({\n\t\t\t\t\t\t...data,\n\t\t\t\t\t\ttype: 'localReplicaInfo',\n\t\t\t\t\t}),\n\t\t\t\t{\n\t\t\t\t\tmode: 'readwrite',\n\t\t\t\t\ttransaction: opts?.transaction,\n\t\t\t\t},\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tthis.ctx.log('critical', 'Error updating local replica', data, e);\n\t\t\tthrow e;\n\t\t}\n\t};\n\n\titerateDocumentBaselines = async (\n\t\trootOid: string,\n\t\titerator: (baseline: DocumentBaseline) => void,\n\t\topts?: CommonQueryOptions,\n\t): Promise<void> => {\n\t\tawait this.iterate(\n\t\t\t'baselines',\n\t\t\t(store) => {\n\t\t\t\tconst root = getOidRoot(rootOid);\n\t\t\t\tconst [start, end] = getOidSubIdRange(rootOid);\n\t\t\t\t// FIXME: get rid of legacy dot OIDs...\n\t\t\t\tconst [dotStart, dotEnd] = getLegacyDotOidSubIdRange(rootOid);\n\t\t\t\treturn [\n\t\t\t\t\tstore.openCursor(IDBKeyRange.only(root)),\n\t\t\t\t\tstore.openCursor(IDBKeyRange.bound(start, end, false, false)),\n\t\t\t\t\tstore.openCursor(IDBKeyRange.bound(dotStart, dotEnd, false, false)),\n\t\t\t\t];\n\t\t\t},\n\t\t\titerator,\n\t\t\topts,\n\t\t);\n\t};\n\n\titerateCollectionBaselines = async (\n\t\tcollection: string,\n\t\titerator: (baseline: DocumentBaseline) => void,\n\t\topts?: CommonQueryOptions,\n\t): Promise<void> => {\n\t\tawait this.iterate(\n\t\t\t'baselines',\n\t\t\t(store) => {\n\t\t\t\treturn [\n\t\t\t\t\tstore.openCursor(\n\t\t\t\t\t\tIDBKeyRange.bound(collection, collection + '\\uffff', false, false),\n\t\t\t\t\t),\n\t\t\t\t];\n\t\t\t},\n\t\t\titerator,\n\t\t\topts,\n\t\t);\n\t};\n\n\titerateAllBaselines = async (\n\t\titerator: Iterator<DocumentBaseline>,\n\t\topts: CommonQueryOptions,\n\t): Promise<void> => {\n\t\tawait this.iterate(\n\t\t\t'baselines',\n\t\t\t(store) => store.index('timestamp').openCursor(),\n\t\t\titerator,\n\t\t\topts,\n\t\t);\n\t};\n\n\tgetBaseline = (\n\t\toid: string,\n\t\topts?: CommonQueryOptions,\n\t): Promise<DocumentBaseline> => {\n\t\treturn this.run<DocumentBaseline>(\n\t\t\t'baselines',\n\t\t\t(store) => store.get(oid),\n\t\t\topts,\n\t\t);\n\t};\n\n\tsetBaselines = async (\n\t\tbaselines: DocumentBaseline[],\n\t\topts: CommonQueryOptions = writeOpts,\n\t): Promise<void> => {\n\t\tawait this.runAll<any>(\n\t\t\t'baselines',\n\t\t\t(store) => baselines.map((b) => store.put(b)),\n\t\t\topts,\n\t\t);\n\t};\n\n\tdeleteBaseline = async (\n\t\toid: string,\n\t\topts: CommonQueryOptions = writeOpts,\n\t): Promise<void> => {\n\t\tawait this.run('baselines', (store) => store.delete(oid), opts);\n\t};\n\n\titerateDocumentOperations = (\n\t\trootOid: string,\n\t\titerator: (op: StoredClientOperation) => void,\n\t\topts?: CommonQueryOptions & { to?: string | null },\n\t): Promise<void> => {\n\t\treturn this.iterate<StoredClientOperation>(\n\t\t\t'operations',\n\t\t\t(store) => {\n\t\t\t\tconst index = store.index('d_t');\n\t\t\t\tconst start = createLowerBoundIndexValue(rootOid);\n\t\t\t\tconst end = opts?.to\n\t\t\t\t\t? createCompoundIndexValue(rootOid, opts.to)\n\t\t\t\t\t: createUpperBoundIndexValue(rootOid);\n\n\t\t\t\tconst range = IDBKeyRange.bound(start, end, false, false);\n\t\t\t\treturn index.openCursor(range);\n\t\t\t},\n\t\t\titerator,\n\t\t\topts,\n\t\t);\n\t};\n\n\titerateEntityOperations = (\n\t\toid: string,\n\t\titerator: (op: StoredClientOperation) => void,\n\t\topts?: CommonQueryOptions & { to?: string | null },\n\t): Promise<void> => {\n\t\t// NOTE: this is simplified from original impl.\n\t\t// perhaps I missed some nuance as to why it was\n\t\t// so complex before?\n\n\t\treturn this.iterate<StoredClientOperation>(\n\t\t\t'operations',\n\t\t\t(store) => {\n\t\t\t\tconst start = createLowerBoundIndexValue(oid);\n\t\t\t\tconst end = opts?.to\n\t\t\t\t\t? createCompoundIndexValue(oid, opts.to)\n\t\t\t\t\t: createUpperBoundIndexValue(oid);\n\n\t\t\t\tconst range = IDBKeyRange.bound(start, end, false, false);\n\t\t\t\treturn store.openCursor(range);\n\t\t\t},\n\t\t\titerator,\n\t\t\topts,\n\t\t);\n\t};\n\n\tdeleteEntityOperations = (\n\t\toid: string,\n\t\topts: CommonQueryOptions & { to: string | null },\n\t): Promise<void> => {\n\t\treturn this.iterate<StoredClientOperation>(\n\t\t\t'operations',\n\t\t\t(store) => {\n\t\t\t\tconst start = createLowerBoundIndexValue(oid);\n\t\t\t\tconst end = opts?.to\n\t\t\t\t\t? createCompoundIndexValue(oid, opts.to)\n\t\t\t\t\t: createUpperBoundIndexValue(oid);\n\n\t\t\t\tconst range = IDBKeyRange.bound(start, end, false, false);\n\t\t\t\treturn store.openCursor(range);\n\t\t\t},\n\t\t\t(op, store) => {\n\t\t\t\tstore.delete(op.oid_timestamp);\n\t\t\t},\n\t\t\topts,\n\t\t);\n\t};\n\n\titerateCollectionOperations = (\n\t\tcollection: string,\n\t\titerator: (op: StoredClientOperation) => void,\n\t\topts?: CommonQueryOptions,\n\t): Promise<void> => {\n\t\treturn this.iterate(\n\t\t\t'operations',\n\t\t\t(store) => {\n\t\t\t\treturn store.openCursor(\n\t\t\t\t\tIDBKeyRange.bound(collection, collection + '\\uffff', false, false),\n\t\t\t\t\t'next',\n\t\t\t\t);\n\t\t\t},\n\t\t\titerator,\n\t\t\topts,\n\t\t);\n\t};\n\n\titerateLocalOperations = (\n\t\titerator: (op: StoredClientOperation) => void,\n\t\topts?: CommonQueryOptions & {\n\t\t\tafter?: string | null;\n\t\t},\n\t): Promise<void> => {\n\t\treturn this.iterate(\n\t\t\t'operations',\n\t\t\t(store) => {\n\t\t\t\tconst start = opts?.after\n\t\t\t\t\t? createCompoundIndexValue(true, opts.after)\n\t\t\t\t\t: createLowerBoundIndexValue(true);\n\t\t\t\tconst end = createUpperBoundIndexValue(true);\n\t\t\t\tconst index = store.index('l_t');\n\t\t\t\treturn index.openCursor(\n\t\t\t\t\t// NOTE: differs from original impl -- last arg is 'false' instead of 'true'\n\t\t\t\t\tIDBKeyRange.bound(start, end, !!opts?.after, false),\n\t\t\t\t\t'next',\n\t\t\t\t);\n\t\t\t},\n\t\t\titerator,\n\t\t);\n\t};\n\n\titerateAllOperations = (\n\t\titerator: (op: StoredClientOperation) => void,\n\t\topts?: CommonQueryOptions & {\n\t\t\tbefore?: string | null;\n\t\t\tfrom?: string | null;\n\t\t},\n\t): Promise<void> => {\n\t\treturn this.iterate(\n\t\t\t'operations',\n\t\t\t(store) => {\n\t\t\t\tconst start = opts?.from\n\t\t\t\t\t? createLowerBoundIndexValue(opts.from)\n\t\t\t\t\t: undefined;\n\t\t\t\tconst end = opts?.before\n\t\t\t\t\t? createUpperBoundIndexValue(opts.before)\n\t\t\t\t\t: createLowerBoundIndexValue(true);\n\t\t\t\tconst range =\n\t\t\t\t\tstart && end\n\t\t\t\t\t\t? IDBKeyRange.bound(start, end, false, true)\n\t\t\t\t\t\t: start\n\t\t\t\t\t\t\t? IDBKeyRange.lowerBound(start, false)\n\t\t\t\t\t\t\t: end\n\t\t\t\t\t\t\t\t? IDBKeyRange.upperBound(end, true)\n\t\t\t\t\t\t\t\t: undefined;\n\t\t\t\treturn store.index('timestamp').openCursor(range, 'next');\n\t\t\t},\n\t\t\titerator,\n\t\t\topts,\n\t\t);\n\t};\n\n\taddOperations = async (\n\t\tops: StoredClientOperation[],\n\t\topts: CommonQueryOptions = writeOpts,\n\t): Promise<ObjectIdentifier[]> => {\n\t\tlet affected = new Set<ObjectIdentifier>();\n\t\tawait this.runAll(\n\t\t\t'operations',\n\t\t\t(store) =>\n\t\t\t\tops.map((op) => {\n\t\t\t\t\taffected.add(getOidRoot(op.oid));\n\t\t\t\t\treturn store.put(this.addOperationIndexes(op));\n\t\t\t\t}),\n\t\t\topts,\n\t\t);\n\t\treturn Array.from(affected);\n\t};\n\n\treset = async ({\n\t\tclearReplica,\n\t\ttransaction,\n\t}: {\n\t\tclearReplica?: boolean;\n\t\ttransaction?: AbstractTransaction;\n\t} = {}): Promise<void> => {\n\t\tconst tx =\n\t\t\t(transaction as IDBTransaction) ||\n\t\t\tthis.createTransaction(['info', 'operations', 'baselines'], {\n\t\t\t\tmode: 'readwrite',\n\t\t\t});\n\t\tawait Promise.all([\n\t\t\tthis.resetLocalReplica(tx, clearReplica),\n\t\t\tthis.resetBaselines(tx),\n\t\t\tthis.resetOperations(tx),\n\t\t]);\n\t};\n\n\tstats = async (): Promise<{\n\t\toperationsSize: { count: number; size: number };\n\t\tbaselinesSize: { count: number; size: number };\n\t}> => {\n\t\tconst ops = await getSizeOfObjectStore(this.db, 'operations');\n\t\tconst baselines = await getSizeOfObjectStore(this.db, 'baselines');\n\t\treturn { operationsSize: ops, baselinesSize: baselines };\n\t};\n\n\tprivate resetLocalReplica = async (tx: IDBTransaction, clear = false) => {\n\t\tif (clear) {\n\t\t\treturn this.run('info', (store) => store.delete('localReplicaInfo'), {\n\t\t\t\tmode: 'readwrite',\n\t\t\t\ttransaction: tx,\n\t\t\t});\n\t\t} else {\n\t\t\tconst localInfo = await this.getLocalReplica({\n\t\t\t\ttransaction: tx,\n\t\t\t});\n\t\t\tif (localInfo) {\n\t\t\t\tlocalInfo.ackedLogicalTime = null;\n\t\t\t\tlocalInfo.lastSyncedLogicalTime = null;\n\t\t\t\tawait this.run(\n\t\t\t\t\t'info',\n\t\t\t\t\t(store) =>\n\t\t\t\t\t\tstore.put({\n\t\t\t\t\t\t\t...localInfo,\n\t\t\t\t\t\t\ttype: 'localReplicaInfo',\n\t\t\t\t\t\t}),\n\t\t\t\t\t{\n\t\t\t\t\t\tmode: 'readwrite',\n\t\t\t\t\t\ttransaction: tx,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate resetBaselines = async (tx: IDBTransaction) => {\n\t\treturn this.clear('baselines', tx);\n\t};\n\n\tprivate resetOperations = async (tx: IDBTransaction) => {\n\t\treturn this.clear('operations', tx);\n\t};\n\n\tprivate addOperationIndexes = (\n\t\top: ClientOperation,\n\t): StoredClientOperation => {\n\t\treturn {\n\t\t\t...op,\n\t\t\toid_timestamp: createCompoundIndexValue(op.oid, op.timestamp) as string,\n\t\t\tl_t: createCompoundIndexValue(op.isLocal, op.timestamp) as string,\n\t\t\td_t: createCompoundIndexValue(getOidRoot(op.oid), op.timestamp) as string,\n\t\t};\n\t};\n}\n\nconst writeOpts = { mode: 'readwrite' } as const;\n", "import { replaceLegacyOidsInObject } from '@verdant-web/common';\nimport { getMetadataDbName } from '../util.js';\nimport { Context } from '../../../context/context.js';\n\nconst migrations = [version1, version2, version3, version4, version5, version6];\nexport const CURRENT_METADATA_VERSION = migrations.length;\n\nexport function openMetadataDatabase({\n\tindexedDB = window.indexedDB,\n\tnamespace,\n\tlog,\n}: {\n\tindexedDB?: IDBFactory;\n\tnamespace: string;\n\tlog?: Context['log'];\n}): Promise<{ wasInitialized: boolean; db: IDBDatabase }> {\n\treturn new Promise<{ wasInitialized: boolean; db: IDBDatabase }>(\n\t\t(resolve, reject) => {\n\t\t\tconst request = indexedDB.open(\n\t\t\t\tgetMetadataDbName(namespace),\n\t\t\t\tCURRENT_METADATA_VERSION,\n\t\t\t);\n\t\t\tlet wasInitialized = false;\n\t\t\trequest.onupgradeneeded = async (event) => {\n\t\t\t\tconst db = request.result;\n\t\t\t\tconst tx = request.transaction!;\n\n\t\t\t\tconst toRun = migrations.slice(event.oldVersion);\n\t\t\t\tfor (const migration of toRun) {\n\t\t\t\t\tawait migration(db, tx);\n\t\t\t\t}\n\n\t\t\t\tawait new Promise((resolve, reject) => {\n\t\t\t\t\ttx.addEventListener('complete', resolve);\n\t\t\t\t\ttx.addEventListener('error', reject);\n\t\t\t\t});\n\n\t\t\t\tif (!event.oldVersion) {\n\t\t\t\t\twasInitialized = true;\n\t\t\t\t}\n\t\t\t};\n\t\t\trequest.onerror = () => {\n\t\t\t\tconsole.error('Error opening database', request.error);\n\t\t\t\treject(request.error);\n\t\t\t};\n\t\t\trequest.onsuccess = () => {\n\t\t\t\tresolve({ db: request.result, wasInitialized });\n\t\t\t};\n\t\t},\n\t);\n}\n\nasync function version1(db: IDBDatabase, tx: IDBTransaction) {\n\tconst baselinesStore = db.createObjectStore('baselines', {\n\t\tkeyPath: 'oid',\n\t});\n\tconst operationsStore = db.createObjectStore('operations', {\n\t\tkeyPath: 'oid_timestamp',\n\t});\n\tconst infoStore = db.createObjectStore('info', { keyPath: 'type' });\n\tbaselinesStore.createIndex('timestamp', 'timestamp');\n\toperationsStore.createIndex('isLocal_timestamp', 'isLocal_timestamp');\n\toperationsStore.createIndex('documentOid_timestamp', 'documentOid_timestamp');\n}\n\n/**\n * 1 -> 2 changes:\n *\n * Consolidate compound index names:\n *\n * Operations:\n * - isLocal_timestamp -> l_t\n * - documentOid_timestamp -> d_t\n */\nasync function version2(db: IDBDatabase, tx: IDBTransaction) {\n\tconst operations = tx.objectStore('operations');\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst cursorReq = operations.openCursor();\n\t\tcursorReq.onsuccess = () => {\n\t\t\t// rename the consolidated fields\n\t\t\tconst cursor = cursorReq.result;\n\t\t\tif (cursor) {\n\t\t\t\tconst { isLocal_timestamp, documentOid_timestamp, ...value } =\n\t\t\t\t\tcursor.value;\n\t\t\t\tcursor.update({\n\t\t\t\t\t...value,\n\t\t\t\t\tl_t: isLocal_timestamp,\n\t\t\t\t\td_t: documentOid_timestamp,\n\t\t\t\t});\n\t\t\t\tcursor.continue();\n\t\t\t} else {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t};\n\t\tcursorReq.onerror = (event) => {\n\t\t\treject(cursorReq.error);\n\t\t};\n\t});\n\t// remove the old indexes\n\toperations.deleteIndex('isLocal_timestamp');\n\toperations.deleteIndex('documentOid_timestamp');\n\t// create the new indexes\n\toperations.createIndex('l_t', 'l_t', { unique: false });\n\toperations.createIndex('o_t', 'o_t', { unique: false });\n\toperations.createIndex('d_t', 'd_t', { unique: false });\n}\n\n/**\n * 2 -> 3 changes:\n *\n * Add timestamp index to operations\n */\nasync function version3(db: IDBDatabase, tx: IDBTransaction) {\n\tconst operations = tx.objectStore('operations');\n\toperations.createIndex('timestamp', 'timestamp');\n}\n\n/**\n * 3 -> 4 changes:\n * Add files store\n */\nasync function version4(db: IDBDatabase, tx: IDBTransaction) {\n\tconst files = db.createObjectStore('files', {\n\t\tkeyPath: 'id',\n\t});\n\tfiles.createIndex('remote', 'remote');\n\tfiles.createIndex('deletedAt', 'deletedAt');\n}\n\n/**\n * 4 -> 5 changes:\n * replace legacy OIDs\n */\nasync function version5(db: IDBDatabase, tx: IDBTransaction) {\n\t// rewrites all baselines and operations to replace legacy OIDs\n\t// with new ones.\n\tconst operations = tx.objectStore('operations');\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst cursorReq = operations.openCursor();\n\t\tcursorReq.onsuccess = () => {\n\t\t\tconst cursor = cursorReq.result;\n\t\t\tif (cursor) {\n\t\t\t\tconst converted = replaceLegacyOidsInObject(cursor.value);\n\t\t\t\t// conversion may change the primary key, so we need to put the\n\t\t\t\t// object back to the store\n\t\t\t\tif (converted.oid_timestamp !== cursor.primaryKey) {\n\t\t\t\t\tcursor.delete();\n\t\t\t\t\toperations.put(converted);\n\t\t\t\t} else {\n\t\t\t\t\tcursor.update(converted);\n\t\t\t\t}\n\t\t\t\tcursor.continue();\n\t\t\t} else {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t};\n\t\tcursorReq.onerror = (event) => {\n\t\t\treject(cursorReq.error);\n\t\t};\n\t});\n\tconst baselines = tx.objectStore('baselines');\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst cursorReq = baselines.openCursor();\n\t\tcursorReq.onsuccess = () => {\n\t\t\tconst cursor = cursorReq.result;\n\t\t\tif (cursor) {\n\t\t\t\tconst converted = replaceLegacyOidsInObject(cursor.value);\n\t\t\t\tif (converted.oid !== cursor.primaryKey) {\n\t\t\t\t\tcursor.delete();\n\t\t\t\t\tbaselines.put(converted);\n\t\t\t\t} else {\n\t\t\t\t\tcursor.update(converted);\n\t\t\t\t}\n\t\t\t\tcursor.continue();\n\t\t\t} else {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t};\n\t\tcursorReq.onerror = (event) => {\n\t\t\treject(cursorReq.error);\n\t\t};\n\t});\n}\n\n// version 5->6: add timestamp to file metadata\nasync function version6(db: IDBDatabase, tx: IDBTransaction) {\n\tconst files = tx.objectStore('files');\n\tfiles.createIndex('timestamp', 'timestamp');\n}\n", "import {\n\tassert,\n\tCollectionCompoundIndexFilter,\n\tCollectionFilter,\n\tcreateCompoundIndexValue,\n\tcreateLowerBoundIndexValue,\n\tcreateUpperBoundIndexValue,\n\tisMatchIndexFilter,\n\tisRangeIndexFilter,\n\tisSortIndexFilter,\n\tisStartsWithIndexFilter,\n\tMatchCollectionIndexFilter,\n\tRangeCollectionIndexFilter,\n\tsanitizeIndexValue,\n\tSortIndexFilter,\n\tStartsWithIndexFilter,\n\tStorageSchema,\n} from '@verdant-web/common';\n\nconst matchIndexToIdbKeyRange = (filter: MatchCollectionIndexFilter) => {\n\treturn IDBKeyRange.only(sanitizeIndexValue(filter.equals));\n};\n\nconst sortIndexToIdbKeyRange = (filter: SortIndexFilter) => {\n\treturn undefined;\n};\n\nconst rangeIndexToIdbKeyRange = (filter: RangeCollectionIndexFilter) => {\n\tconst lower = filter.gte || filter.gt;\n\tconst upper = filter.lte || filter.lt;\n\tif (lower === upper) {\n\t\treturn IDBKeyRange.only(sanitizeIndexValue(lower));\n\t}\n\tif (!lower) {\n\t\treturn IDBKeyRange.upperBound(sanitizeIndexValue(upper), !!filter.lt);\n\t} else if (!upper) {\n\t\treturn IDBKeyRange.lowerBound(sanitizeIndexValue(lower), !!filter.gt);\n\t} else {\n\t\treturn IDBKeyRange.bound(\n\t\t\tsanitizeIndexValue(lower),\n\t\t\tsanitizeIndexValue(upper),\n\t\t\t!!filter.gt,\n\t\t\t!!filter.lt,\n\t\t);\n\t}\n};\n\nconst compoundIndexToIdbKeyRange = (\n\t// FIXME:\n\tschema: any,\n\tcollection: string,\n\tfilter: CollectionCompoundIndexFilter,\n) => {\n\t// validate the usage of the compound index:\n\t// - all match fields must be contiguous at the start of the compound order\n\tconst indexDefinition =\n\t\tschema.collections[collection].compounds[filter.where];\n\tassert(\n\t\tindexDefinition,\n\t\t`Index ${filter.where} does not exist on collection ${collection}`,\n\t);\n\tconst matchedKeys = Object.keys(filter.match).sort(\n\t\t(a, b) => indexDefinition.of.indexOf(a) - indexDefinition.of.indexOf(b),\n\t);\n\tfor (const key of matchedKeys) {\n\t\tif (indexDefinition.of.indexOf(key) !== matchedKeys.indexOf(key)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Compound index ${filter.where} does not have ${key} at the start of its order`,\n\t\t\t);\n\t\t}\n\t}\n\n\tconst matchedValues = matchedKeys.map(\n\t\t(key) => filter.match[key as keyof typeof filter.match] as string | number,\n\t);\n\n\t// special case: all match fields are specified - we don't need a range\n\t// query, just a single key query\n\tif (matchedKeys.length === indexDefinition.of.length) {\n\t\treturn IDBKeyRange.only(createCompoundIndexValue(...matchedValues));\n\t}\n\n\t// create our bounds for the matched values\n\tconst lower = createLowerBoundIndexValue(...matchedValues);\n\tconst upper = createUpperBoundIndexValue(...matchedValues);\n\treturn IDBKeyRange.bound(lower, upper);\n};\n\nfunction startsWithIndexToIdbKeyRange(filter: StartsWithIndexFilter) {\n\tconst lower = filter.startsWith;\n\tconst upper = filter.startsWith + '\\uffff';\n\treturn IDBKeyRange.bound(lower, upper);\n}\n\nexport function getRange(\n\tschema: StorageSchema,\n\tcollection: string,\n\tindex?: CollectionFilter,\n) {\n\tif (!index) return undefined;\n\tif (isRangeIndexFilter(index)) return rangeIndexToIdbKeyRange(index);\n\tif (isMatchIndexFilter(index)) return matchIndexToIdbKeyRange(index);\n\tif (isSortIndexFilter(index)) return sortIndexToIdbKeyRange(index);\n\tif (isStartsWithIndexFilter(index))\n\t\treturn startsWithIndexToIdbKeyRange(index);\n\treturn compoundIndexToIdbKeyRange(schema, collection, index);\n}\n", "import {\n\tCollectionFilter,\n\tcreateOid,\n\tdecomposeOid,\n\tgetIndexValues,\n\tObjectIdentifier,\n} from '@verdant-web/common';\nimport { ContextWithoutPersistence } from '../../../context/context.js';\nimport { PersistenceDocumentDb } from '../../interfaces.js';\nimport { IdbService } from '../IdbService.js';\nimport {\n\tcloseDatabase,\n\tgetSizeOfObjectStore,\n\tisAbortError,\n\tisTransactionAborted,\n} from '../util.js';\nimport { getRange } from './ranges.js';\n\nexport class IdbDocumentDb extends IdbService implements PersistenceDocumentDb {\n\tconstructor(\n\t\tdb: IDBDatabase,\n\t\tprivate context: ContextWithoutPersistence,\n\t) {\n\t\tsuper(db, context);\n\t\tthis.addDispose(() => {\n\t\t\tthis.context.log(\n\t\t\t\t'info',\n\t\t\t\t'Closing document database for',\n\t\t\t\tcontext.namespace,\n\t\t\t);\n\t\t\treturn closeDatabase(this.db);\n\t\t});\n\t}\n\n\tclose = async () => {\n\t\tawait this.dispose();\n\t};\n\n\tstats = async (): Promise<\n\t\tRecord<string, { count: number; size: number }>\n\t> => {\n\t\tconst collectionNames = Object.keys(this.context.schema.collections);\n\t\tconst collections: Record<string, { count: number; size: number }> = {};\n\t\tawait Promise.all(\n\t\t\tcollectionNames.map(async (name) => {\n\t\t\t\tconst size = await getSizeOfObjectStore(this.db, name);\n\t\t\t\tcollections[name] = size;\n\t\t\t}),\n\t\t);\n\t\treturn collections;\n\t};\n\n\tfindOneOid = async (opts: {\n\t\tcollection: string;\n\t\tindex?: CollectionFilter;\n\t}): Promise<ObjectIdentifier | null> => {\n\t\tconst result = await this.run<IDBCursorWithValue | null>(\n\t\t\topts.collection,\n\t\t\t(store) => {\n\t\t\t\tconst source = opts.index?.where\n\t\t\t\t\t? store.index(opts.index.where)\n\t\t\t\t\t: store;\n\t\t\t\tconst direction = opts.index?.order === 'desc' ? 'prev' : 'next';\n\t\t\t\tconst range = getRange(\n\t\t\t\t\tthis.context.schema,\n\t\t\t\t\topts.collection,\n\t\t\t\t\topts.index,\n\t\t\t\t);\n\t\t\t\treturn source.openCursor(range, direction);\n\t\t\t},\n\t\t\t{ mode: 'readonly' },\n\t\t);\n\t\tif (result) {\n\t\t\treturn createOid(opts.collection, result.primaryKey.toString());\n\t\t}\n\t\treturn null;\n\t};\n\tfindAllOids = async ({\n\t\tcollection,\n\t\tindex,\n\t\toffset,\n\t\tlimit,\n\t}: {\n\t\tcollection: string;\n\t\tindex?: CollectionFilter;\n\t\tlimit?: number;\n\t\toffset?: number;\n\t}): Promise<{ result: ObjectIdentifier[]; hasNextPage: boolean }> => {\n\t\tconst tx = this.createTransaction([collection], { mode: 'readonly' });\n\t\tif (isTransactionAborted(tx)) {\n\t\t\treturn { result: [], hasNextPage: false };\n\t\t}\n\t\tconst store = tx.objectStore(collection);\n\t\tconst source = index?.where ? store.index(index.where) : store;\n\t\tconst direction = index?.order === 'desc' ? 'prev' : 'next';\n\t\tconst range = getRange(this.context.schema, collection, index);\n\t\tconst request = source.openCursor(range, direction);\n\n\t\tlet hasNextPage = false;\n\t\tconst result = await new Promise<string[]>((resolve, reject) => {\n\t\t\tlet hasDoneOffset = !offset;\n\t\t\tlet visited = 0;\n\t\t\tconst results = new Set<ObjectIdentifier>();\n\n\t\t\trequest.onsuccess = () => {\n\t\t\t\tvisited++;\n\t\t\t\tconst cursor = request.result as IDBCursorWithValue | null;\n\t\t\t\tif (!cursor) {\n\t\t\t\t\tresolve(Array.from(results));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// first offset, if we have one. cursor opens at beginning.\n\t\t\t\tif (offset && !hasDoneOffset) {\n\t\t\t\t\tcursor.advance(offset);\n\t\t\t\t\thasDoneOffset = true;\n\t\t\t\t\t// next iteration we begin adding results.\n\t\t\t\t} else {\n\t\t\t\t\t// add result to set, unless we have reached limit.\n\t\t\t\t\tif (!limit || results.size < limit) {\n\t\t\t\t\t\tresults.add(createOid(collection, cursor.primaryKey.toString()));\n\t\t\t\t\t}\n\t\t\t\t\t// even if we reached limit, we keep going one more to check if there's\n\t\t\t\t\t// a next page.\n\t\t\t\t\tif (limit && visited > limit) {\n\t\t\t\t\t\thasNextPage = true;\n\t\t\t\t\t\t// stop iteration here; we reached limit and we have next page\n\t\t\t\t\t\t// info we need.\n\t\t\t\t\t\tresolve(Array.from(results));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcursor.continue();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\trequest.onerror = () => {\n\t\t\t\tif (request.error?.name === 'InvalidStateError') {\n\t\t\t\t\tthis.context.log(\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t`find query failed with InvalidStateError`,\n\t\t\t\t\t\trequest.error,\n\t\t\t\t\t);\n\t\t\t\t\tresolve([]);\n\t\t\t\t} else if (request.error && isAbortError(request.error)) {\n\t\t\t\t\tresolve([]);\n\t\t\t\t} else {\n\t\t\t\t\treject(request.error);\n\t\t\t\t}\n\t\t\t};\n\t\t});\n\n\t\treturn {\n\t\t\tresult,\n\t\t\thasNextPage,\n\t\t};\n\t};\n\n\tsaveEntities = async (\n\t\tentities: { oid: ObjectIdentifier; getSnapshot: () => any }[],\n\t\toptsAndInfo: { abort?: AbortSignal; collections: string[] },\n\t): Promise<void> => {\n\t\tconst options = {\n\t\t\ttransaction: this.createTransaction(optsAndInfo.collections, {\n\t\t\t\tmode: 'readwrite',\n\t\t\t\tabort: optsAndInfo.abort,\n\t\t\t}),\n\t\t};\n\n\t\tconst results = await Promise.allSettled(\n\t\t\tentities.map(async (e) => {\n\t\t\t\tconst snapshot = e.getSnapshot();\n\t\t\t\ttry {\n\t\t\t\t\tawait this.saveDocument(e.oid, snapshot, options);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthis.context.log(\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t`Error saving document ${e.oid} (${JSON.stringify(snapshot)})`,\n\t\t\t\t\t\terr,\n\t\t\t\t\t);\n\t\t\t\t\tif (err instanceof Error) {\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new Error('Unknown error saving document');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\n\t\tconst failures = results.filter((r) => r.status === 'rejected');\n\t\tif (failures.length) {\n\t\t\t// in the case of a failure to save a document, it doesn't quite make sense to cancel or rollback whatever is\n\t\t\t// currently happening. when restoring imports, etc, this makes the app stuck. if only a few docs failed, maybe\n\t\t\t// there's some data corruption somewhere, but we can just lose those without affecting the rest of the data.\n\t\t\tif (failures.length === results.length) {\n\t\t\t\t// but if ALL of them failed, that's trouble...\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Failed to save any documents. Something must be quite wrong.',\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.context.log(\n\t\t\t\t'error',\n\t\t\t\t'Failed to save documents:',\n\t\t\t\tfailures,\n\t\t\t\t\". See logs above. This only affects querying these documents. Let's hope a future attempt will correct them...\",\n\t\t\t);\n\t\t}\n\n\t\toptions.transaction.commit();\n\t};\n\n\treset = async (): Promise<void> => {\n\t\tconst names = Object.keys(this.context.schema.collections);\n\t\tconst tx = this.createTransaction(names, { mode: 'readwrite' });\n\t\tawait Promise.all(\n\t\t\tnames.map((name) =>\n\t\t\t\tthis.run(name, (store) => store.clear(), { transaction: tx }),\n\t\t\t),\n\t\t);\n\t\tthis.context.entityEvents.emit('collectionsChanged', names);\n\t\tthis.context.log('info', '\uD83D\uDCA8 Reset queryable storage');\n\t};\n\n\tprivate saveDocument = async (\n\t\toid: ObjectIdentifier,\n\t\tdoc: any,\n\t\t{ transaction }: { transaction?: IDBTransaction },\n\t) => {\n\t\tthis.context.log('debug', `Saving document indexes for querying ${oid}`);\n\t\tconst { collection, id } = decomposeOid(oid);\n\t\ttry {\n\t\t\tif (!doc) {\n\t\t\t\tawait this.run(collection, (store) => store.delete(id), {\n\t\t\t\t\tmode: 'readwrite',\n\t\t\t\t\ttransaction,\n\t\t\t\t});\n\t\t\t\tthis.context.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t`Deleted document indexes for querying ${oid}`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst schema = this.context.schema.collections[collection];\n\t\t\t\t// no need to validate before storing; the entity's snapshot is already validated.\n\t\t\t\tconst indexes = getIndexValues(schema, doc);\n\t\t\t\tindexes['@@@snapshot'] = JSON.stringify(doc);\n\t\t\t\tawait this.run(collection, (store) => store.put(indexes), {\n\t\t\t\t\tmode: 'readwrite',\n\t\t\t\t\ttransaction,\n\t\t\t\t});\n\t\t\t\tthis.context.log('debug', `Save complete for ${oid}`, indexes);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthis.context.log('error', `Error saving document ${oid}`, err);\n\t\t\tthrow err;\n\t\t}\n\t};\n}\n", "import { Context } from '../../../../internal.js';\nimport {\n\topenDatabase as baseOpenDatabase,\n\tcloseDatabase,\n\tgetDocumentDbName,\n\tglobalIDB,\n\tstoreRequestPromise,\n} from '../../util.js';\n\n/**\n * Upgrades the database to the given version, using the given upgrader function.\n */\nexport async function upgradeDatabase(\n\tindexedDb: IDBFactory,\n\tnamespace: string,\n\tversion: number,\n\tupgrader: (\n\t\ttransaction: IDBTransaction,\n\t\tdb: IDBDatabase,\n\t\tevent: IDBVersionChangeEvent,\n\t) => void,\n\tlog?: (...args: any[]) => void,\n): Promise<IDBDatabase> {\n\tlog?.('debug', 'Upgrading database', namespace, 'to version', version);\n\tfunction openAndUpgrade(\n\t\tresolve: (db: IDBDatabase) => void,\n\t\treject: (err: Error) => void,\n\t) {\n\t\tconst request = indexedDb.open(getDocumentDbName(namespace), version);\n\t\tlet wasUpgraded = false;\n\t\trequest.onupgradeneeded = (event) => {\n\t\t\tconst transaction = request.transaction!;\n\t\t\tupgrader(transaction, request.result, event);\n\t\t\twasUpgraded = true;\n\t\t};\n\t\trequest.onsuccess = async (event) => {\n\t\t\tif (wasUpgraded) {\n\t\t\t\t// close the database\n\t\t\t\tawait closeDatabase(request.result);\n\t\t\t\tresolve(request.result);\n\t\t\t} else {\n\t\t\t\treject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t'Database was not upgraded when a version change was expected',\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\t\trequest.onerror = (event) => {\n\t\t\treject(request.error || new Error('Unknown error'));\n\t\t};\n\t\trequest.onblocked = (event) => {\n\t\t\tlog?.('Database upgrade blocked!');\n\t\t};\n\t}\n\treturn new Promise<IDBDatabase>(openAndUpgrade);\n}\n\nexport async function openDatabase({\n\tindexedDB = globalIDB,\n\tnamespace,\n\tversion,\n\tlog,\n}: {\n\tindexedDB?: IDBFactory;\n\tnamespace: string;\n\tversion: number;\n\tlog?: Context['log'];\n}): Promise<IDBDatabase> {\n\tif (version <= 0) {\n\t\tthrow new Error('Cannot open database at version less than 1');\n\t}\n\tlog?.('debug', 'Opening database', namespace, 'at version', version);\n\tconst db = await baseOpenDatabase(\n\t\tgetDocumentDbName(namespace),\n\t\tversion,\n\t\tindexedDB,\n\t);\n\tlog?.('debug', 'Database opened', namespace, 'at version', db.version);\n\tif (db.version !== version) {\n\t\tlog?.(\n\t\t\t'warn',\n\t\t\t`Opened database version ${db.version} but expected version ${version} for namespace ${namespace}`,\n\t\t);\n\t}\n\n\tdb.addEventListener('versionchange', (event) => {\n\t\tdb.close();\n\t});\n\n\tdb.addEventListener('close', () => {\n\t\tlog?.('warn', 'Database closed', namespace);\n\t});\n\n\treturn db;\n}\n\nexport async function copyAll(\n\tsourceDatabase: IDBDatabase,\n\ttargetDatabase: IDBDatabase,\n) {\n\t// DOMStringList... doesn't have iterable... why\n\tconst sourceStoreNames = new Array<string>();\n\tfor (let i = 0; i < sourceDatabase.objectStoreNames.length; i++) {\n\t\tsourceStoreNames.push(sourceDatabase.objectStoreNames[i]);\n\t}\n\n\tconst copyFromTransaction = sourceDatabase.transaction(\n\t\tsourceStoreNames,\n\t\t'readonly',\n\t);\n\tconst copyFromStores = sourceStoreNames.map((name) =>\n\t\tcopyFromTransaction.objectStore(name),\n\t);\n\tconst allObjects = await Promise.all(\n\t\tcopyFromStores.map((store) => storeRequestPromise(store.getAll())),\n\t);\n\n\tconst copyToTransaction = targetDatabase.transaction(\n\t\tsourceStoreNames,\n\t\t'readwrite',\n\t);\n\tconst copyToStores = sourceStoreNames.map((name) =>\n\t\tcopyToTransaction.objectStore(name),\n\t);\n\n\tfor (let i = 0; i < copyToStores.length; i++) {\n\t\tawait Promise.all(\n\t\t\tallObjects[i].map((obj) => {\n\t\t\t\treturn storeRequestPromise(copyToStores[i].put(obj));\n\t\t\t}),\n\t\t);\n\t}\n}\n", "import { Migration } from '@verdant-web/common';\nimport { ContextWithoutPersistence } from '../../context/context.js';\nimport {\n\tPersistenceFileDb,\n\tPersistenceImplementation,\n\tPersistenceNamespace,\n} from '../interfaces.js';\nimport { IdbPersistenceFileDb } from './files/IdbPersistenceFileDb.js';\nimport { IdbMetadataDb } from './metadata/IdbMetadataDb.js';\nimport { openMetadataDatabase } from './metadata/openMetadataDatabase.js';\nimport { IdbDocumentDb } from './queries/IdbDocumentDb.js';\nimport { openDatabase, upgradeDatabase } from './queries/migration/db.js';\nimport {\n\tcloseDatabase,\n\tdeleteDatabase,\n\tgetDocumentDbName,\n\tgetMetadataDbName,\n\tgetNamespaceFromDatabaseInfo,\n\toverwriteDatabase,\n} from './util.js';\n\nexport class IdbPersistence implements PersistenceImplementation {\n\tname = 'IdbPersistence';\n\tconstructor(private indexedDB: IDBFactory = window.indexedDB) {}\n\n\tgetNamespaces = async (): Promise<string[]> => {\n\t\t// list all idb database names\n\t\tconst dbs = await this.indexedDB.databases();\n\t\treturn Array.from(\n\t\t\tnew Set<string>(\n\t\t\t\tdbs.map(getNamespaceFromDatabaseInfo).filter((n): n is string => !!n),\n\t\t\t),\n\t\t);\n\t};\n\n\tgetNamespaceVersion = async (namespace: string): Promise<number> => {\n\t\tconst databaseName = getDocumentDbName(namespace);\n\t\tconst dbInfo = await this.indexedDB.databases();\n\t\tconst existingDb = dbInfo.find((info) => info.name === databaseName);\n\t\tif (existingDb) {\n\t\t\treturn existingDb.version ?? 0;\n\t\t}\n\n\t\treturn 0;\n\t};\n\n\tdeleteNamespace = async (namespace: string): Promise<void> => {\n\t\tawait Promise.all([\n\t\t\tdeleteDatabase(getMetadataDbName(namespace), this.indexedDB),\n\t\t\tdeleteDatabase([namespace, 'collections'].join('_'), this.indexedDB),\n\t\t]);\n\t};\n\n\topenNamespace = async (\n\t\tnamespace: string,\n\t): Promise<IdbPersistenceNamespace> => {\n\t\treturn new IdbPersistenceNamespace(this.indexedDB, namespace);\n\t};\n\n\tcopyNamespace = async (\n\t\tfrom: string,\n\t\tto: string,\n\t\tctx: ContextWithoutPersistence,\n\t): Promise<void> => {\n\t\tconst fromCtx = ctx.cloneWithOptions({\n\t\t\tnamespace: from,\n\t\t}) as ContextWithoutPersistence;\n\t\tconst toCtx = ctx.cloneWithOptions({\n\t\t\tnamespace: to,\n\t\t}) as ContextWithoutPersistence;\n\t\tconst { db: fromMetaDb } = await openMetadataDatabase({\n\t\t\tindexedDB: this.indexedDB,\n\t\t\tlog: fromCtx.log,\n\t\t\tnamespace: fromCtx.namespace,\n\t\t});\n\n\t\t// no need to involve files, as they store all data\n\t\t// in the metadata database.\n\n\t\tconst fromDocumentsDb = await openDatabase({\n\t\t\tindexedDB: this.indexedDB,\n\t\t\tnamespace: fromCtx.namespace,\n\t\t\tversion: fromCtx.schema.version,\n\t\t\tlog: fromCtx.log,\n\t\t});\n\n\t\tfromCtx.log(\n\t\t\t'info',\n\t\t\t`Copying data from ${fromCtx.namespace} to ${toCtx.namespace}`,\n\t\t);\n\n\t\tawait overwriteDatabase(\n\t\t\tfromMetaDb,\n\t\t\tgetMetadataDbName(toCtx.namespace),\n\t\t\ttoCtx,\n\t\t\tthis.indexedDB,\n\t\t);\n\t\tawait overwriteDatabase(\n\t\t\tfromDocumentsDb,\n\t\t\tgetDocumentDbName(toCtx.namespace),\n\t\t\ttoCtx,\n\t\t\tthis.indexedDB,\n\t\t);\n\n\t\tawait closeDatabase(fromMetaDb);\n\t\tawait closeDatabase(fromDocumentsDb);\n\t};\n}\n\nclass IdbPersistenceNamespace implements PersistenceNamespace {\n\tconstructor(\n\t\tprivate indexedDB: IDBFactory,\n\t\tprivate namespace: string,\n\t) {}\n\tprivate metadataDb: IDBDatabase | undefined;\n\n\topenFiles(ctx: ContextWithoutPersistence): Promise<PersistenceFileDb> {\n\t\tif (!this.metadataDb) {\n\t\t\tthrow new Error(\n\t\t\t\t'Metadata database must be opened first. This is a bug in Verdant.',\n\t\t\t);\n\t\t}\n\t\treturn Promise.resolve(new IdbPersistenceFileDb(this.metadataDb, ctx));\n\t}\n\n\topenMetadata = async (ctx: ContextWithoutPersistence) => {\n\t\tconst { db } = await openMetadataDatabase({\n\t\t\tindexedDB: this.indexedDB,\n\t\t\tlog: ctx.log,\n\t\t\tnamespace: this.namespace,\n\t\t});\n\t\tthis.metadataDb = db;\n\t\tctx.persistenceShutdownHandler.register(() => closeDatabase(db));\n\t\treturn new IdbMetadataDb(db, ctx);\n\t};\n\n\topenDocuments = async (ctx: ContextWithoutPersistence) => {\n\t\tconst db = await openDatabase({\n\t\t\tversion: ctx.schema.version,\n\t\t\tindexedDB: this.indexedDB,\n\t\t\tlog: ctx.log,\n\t\t\tnamespace: this.namespace,\n\t\t});\n\t\tctx.persistenceShutdownHandler.register(() => closeDatabase(db));\n\t\treturn new IdbDocumentDb(db, ctx);\n\t};\n\n\tapplyMigration = async (\n\t\tctx: ContextWithoutPersistence,\n\t\tmigration: Migration<any>,\n\t): Promise<void> => {\n\t\tctx.log(\n\t\t\t'debug',\n\t\t\t'Applying migration',\n\t\t\tmigration.newSchema.version,\n\t\t\tmigration,\n\t\t);\n\t\tawait upgradeDatabase(\n\t\t\tthis.indexedDB,\n\t\t\tthis.namespace,\n\t\t\tmigration.newSchema.version,\n\t\t\t(transaction, db) => {\n\t\t\t\tfor (const newCollection of migration.addedCollections) {\n\t\t\t\t\tdb.createObjectStore(newCollection, {\n\t\t\t\t\t\tkeyPath: migration.newSchema.collections[newCollection].primaryKey,\n\t\t\t\t\t\tautoIncrement: false,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tfor (const collection of migration.allCollections) {\n\t\t\t\t\tif (!db.objectStoreNames.contains(collection)) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Expected object store for collection ${collection} to exist during migration, but it did not`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconst store = transaction.objectStore(collection);\n\t\t\t\t\t// apply new indexes\n\t\t\t\t\tfor (const newIndex of migration.addedIndexes[collection] || []) {\n\t\t\t\t\t\tstore.createIndex(newIndex.name, newIndex.name, {\n\t\t\t\t\t\t\tmultiEntry: newIndex.multiEntry,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// remove old indexes\n\t\t\t\t\tfor (const oldIndex of migration.removedIndexes[collection] || []) {\n\t\t\t\t\t\tstore.deleteIndex(oldIndex.name);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor (const removedCollection of migration.removedCollections) {\n\t\t\t\t\t// !! can't delete the store, because old operations that relate to\n\t\t\t\t\t// this store may still exist in history. instead, we can clear it out\n\t\t\t\t\t// and leave it in place\n\t\t\t\t\ttransaction.objectStore(removedCollection).clear();\n\t\t\t\t}\n\t\t\t},\n\t\t\tctx.log,\n\t\t);\n\t};\n}\n", "export class ShutdownHandler {\n\tprivate consumed = false;\n\tprivate readonly handlers: (() => Promise<void>)[] = [];\n\tconstructor(\n\t\tprivate log?: (\n\t\t\tlevel: 'debug' | 'info' | 'warn' | 'error' | 'critical',\n\t\t\t...args: any[]\n\t\t) => void,\n\t) {}\n\n\tregister(handler: () => Promise<void>) {\n\t\tthis.handlers.push(handler);\n\t}\n\n\tasync shutdown() {\n\t\tif (this.consumed) {\n\t\t\tthis.log?.('warn', 'ShutdownHandler already consumed');\n\t\t}\n\n\t\tthis.consumed = true;\n\t\tawait Promise.all(this.handlers.map((handler) => handler()));\n\t\tthis.handlers.length = 0;\n\t}\n\n\tget isShuttingDown() {\n\t\treturn this.consumed;\n\t}\n\n\treset = () => {\n\t\tthis.consumed = false;\n\t};\n}\n", "import { hashObject, StorageSchema } from '@verdant-web/common';\n\nexport function getWipNamespace(namespace: string, schema: StorageSchema) {\n\treturn `@@wip-${namespace}-${hashObject(schema)}`;\n}\n", "import {\n\tAuthorizationKey,\n\tCollectionFilter,\n\tMigration,\n\tMigrationEngine,\n\tObjectIdentifier,\n\taddFieldDefaults,\n\tassert,\n\tassignOidsToAllSubObjects,\n\tcloneDeep,\n\tcreateOid,\n\tdiffToPatches,\n\tgetOid,\n\tremoveOidPropertiesFromAllSubObjects,\n} from '@verdant-web/common';\nimport { ContextWithoutPersistence } from '../../context/context.js';\nimport { PersistenceDocumentDb, PersistenceNamespace } from '../interfaces.js';\nimport { PersistenceMetadata } from '../PersistenceMetadata.js';\n\nfunction getMigrationMutations({\n\tmigration,\n\tnewOids,\n\tctx,\n\tmeta,\n}: {\n\tmigration: Migration<any>;\n\tnewOids: string[];\n\tctx: ContextWithoutPersistence;\n\tmeta: PersistenceMetadata;\n}) {\n\treturn migration.allCollections.reduce((acc, collectionName) => {\n\t\tacc[collectionName] = {\n\t\t\tput: async (doc: any, options?: { access?: AuthorizationKey }) => {\n\t\t\t\t// add defaults\n\t\t\t\taddFieldDefaults(migration.newSchema.collections[collectionName], doc);\n\t\t\t\tconst primaryKey =\n\t\t\t\t\tdoc[migration.newSchema.collections[collectionName].primaryKey];\n\t\t\t\tconst oid = createOid(collectionName, primaryKey);\n\t\t\t\tnewOids.push(oid);\n\n\t\t\t\tawait ctx.time.withMigrationTime(migration.version, () =>\n\t\t\t\t\tmeta.insertData({\n\t\t\t\t\t\toperations: ctx.patchCreator.createInitialize(\n\t\t\t\t\t\t\tdoc,\n\t\t\t\t\t\t\toid,\n\t\t\t\t\t\t\toptions?.access,\n\t\t\t\t\t\t),\n\t\t\t\t\t\tisLocal: true,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn doc;\n\t\t\t},\n\t\t\tdelete: async (id: string) => {\n\t\t\t\tconst rootOid = createOid(collectionName, id);\n\t\t\t\tawait ctx.time.withMigrationTime(migration.version, () =>\n\t\t\t\t\tmeta.deleteDocument(rootOid),\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\t\treturn acc;\n\t}, {} as any);\n}\n\nfunction getMigrationQueries({\n\tmigration,\n\tcontext,\n\tdocuments,\n\tmeta,\n}: {\n\tmigration: Migration<any>;\n\tcontext: ContextWithoutPersistence;\n\tdocuments: PersistenceDocumentDb;\n\tmeta: PersistenceMetadata;\n}) {\n\treturn migration.oldCollections.reduce((acc, collectionName) => {\n\t\tacc[collectionName] = {\n\t\t\tget: async (id: string) => {\n\t\t\t\tconst oid = createOid(collectionName, id);\n\t\t\t\tconst doc = await meta.getDocumentSnapshot(oid, {\n\t\t\t\t\t// only get the snapshot up to the previous version (newer operations may have synced)\n\t\t\t\t\tto: context.time.nowWithVersion(migration.oldSchema.version),\n\t\t\t\t});\n\t\t\t\treturn doc;\n\t\t\t},\n\t\t\tfindOne: async (filter: CollectionFilter) => {\n\t\t\t\tconst oid = await documents.findOneOid({\n\t\t\t\t\tcollection: collectionName,\n\t\t\t\t\tindex: filter,\n\t\t\t\t});\n\t\t\t\tif (!oid) return null;\n\t\t\t\tconst doc = await meta.getDocumentSnapshot(oid, {\n\t\t\t\t\t// only get the snapshot up to the previous version (newer operations may have synced)\n\t\t\t\t\tto: context.time.nowWithVersion(migration.oldSchema.version),\n\t\t\t\t});\n\t\t\t\treturn doc;\n\t\t\t},\n\t\t\tfindAll: async (filter: CollectionFilter) => {\n\t\t\t\tconst { result: oids } = await documents.findAllOids({\n\t\t\t\t\tcollection: collectionName,\n\t\t\t\t\tindex: filter,\n\t\t\t\t});\n\t\t\t\tconst docs = await Promise.all(\n\t\t\t\t\toids.map(async (oid) =>\n\t\t\t\t\t\tmeta.getDocumentSnapshot(oid, {\n\t\t\t\t\t\t\t// only get the snapshot up to the previous version (newer operations may have synced)\n\t\t\t\t\t\t\tto: context.time.nowWithVersion(migration.oldSchema.version),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn docs;\n\t\t\t},\n\t\t};\n\t\treturn acc;\n\t}, {} as any);\n}\n\nexport async function getMigrationEngine({\n\tmigration,\n\tcontext,\n\tns,\n\tmeta,\n}: {\n\tlog?: (...args: any[]) => void;\n\tmigration: Migration;\n\tcontext: ContextWithoutPersistence;\n\tns: PersistenceNamespace;\n\tmeta: PersistenceMetadata;\n}): Promise<MigrationEngine> {\n\tconst migrationContext = context.cloneWithOptions({\n\t\tschema: migration.oldSchema,\n\t});\n\tif (migration.oldSchema.version === 0) {\n\t\treturn getInitialMigrationEngine({\n\t\t\tmigration,\n\t\t\tcontext: migrationContext,\n\t\t\tmeta,\n\t\t});\n\t}\n\n\tconst newOids = new Array<ObjectIdentifier>();\n\n\tconst documents = await ns.openDocuments(migrationContext);\n\tconst queries = getMigrationQueries({\n\t\tmigration,\n\t\tcontext: migrationContext,\n\t\tdocuments,\n\t\tmeta,\n\t});\n\tconst mutations = getMigrationMutations({\n\t\tmigration,\n\t\tnewOids,\n\t\tctx: migrationContext,\n\t\tmeta,\n\t});\n\tconst deleteCollection = async (collection: string) => {\n\t\tawait meta.deleteCollection(collection);\n\t};\n\tconst awaitables = new Array<Promise<any>>();\n\tconst engine: MigrationEngine = {\n\t\tlog: context.log,\n\t\tnewOids,\n\t\tdeleteCollection,\n\t\tmigrate: async (collection, strategy) => {\n\t\t\tconst docs = await queries[collection].findAll();\n\t\t\tcontext.log(\n\t\t\t\t'debug',\n\t\t\t\t`Migrating ${docs.length} documents in ${collection}`,\n\t\t\t);\n\n\t\t\tawait Promise.all(\n\t\t\t\tdocs.filter(Boolean).map(async (doc: any) => {\n\t\t\t\t\tconst rootOid = getOid(doc);\n\t\t\t\t\tassert(\n\t\t\t\t\t\t!!rootOid,\n\t\t\t\t\t\t`Document is missing an OID: ${JSON.stringify(doc)}`,\n\t\t\t\t\t);\n\t\t\t\t\t// FIXME: this could be optimized (making n queries for authz\n\t\t\t\t\t// when the snapshots themselves are derived from the same data...)\n\t\t\t\t\t// maybe don't use the findAll query, and instead go a level\n\t\t\t\t\t// lower to retain access to lower level data here?\n\t\t\t\t\tconst authz = await meta.getDocumentAuthz(rootOid);\n\t\t\t\t\tconst original = cloneDeep(doc);\n\t\t\t\t\t// @ts-ignore - excessive type resolution\n\t\t\t\t\tconst newValue = await strategy(doc);\n\t\t\t\t\tif (newValue) {\n\t\t\t\t\t\t// the migration has altered the shape of our document. we need\n\t\t\t\t\t\t// to create the operation from the diff and write it to meta as\n\t\t\t\t\t\t// a migration patch\n\t\t\t\t\t\tremoveOidPropertiesFromAllSubObjects(original);\n\t\t\t\t\t\tremoveOidPropertiesFromAllSubObjects(newValue);\n\t\t\t\t\t\tassignOidsToAllSubObjects(newValue);\n\t\t\t\t\t\tconst patches = diffToPatches(\n\t\t\t\t\t\t\toriginal,\n\t\t\t\t\t\t\tnewValue,\n\t\t\t\t\t\t\t() => context.time.zeroWithVersion(migration.version),\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t[],\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// incoming unknown objects are assumed to be the same\n\t\t\t\t\t\t\t\t// as any pre-existing object.\n\t\t\t\t\t\t\t\tmergeUnknownObjects: true,\n\t\t\t\t\t\t\t\t// if a field is undefined in the new value, it should be\n\t\t\t\t\t\t\t\t// erased. this is the only way to allow users to remove\n\t\t\t\t\t\t\t\t// entries in maps during migrations. it is a little\n\t\t\t\t\t\t\t\t// dangerous for other types, though.\n\t\t\t\t\t\t\t\tdefaultUndefined: false,\n\t\t\t\t\t\t\t\tauthz,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (patches.length > 0) {\n\t\t\t\t\t\t\tawait meta.insertData({\n\t\t\t\t\t\t\t\toperations: patches,\n\t\t\t\t\t\t\t\tisLocal: true,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t\tqueries,\n\t\tmutations,\n\t\tawaitables,\n\t\tclose: async () => {\n\t\t\tawait documents.close();\n\t\t},\n\t};\n\treturn engine;\n}\n\nfunction getInitialMigrationEngine({\n\tmigration,\n\tcontext,\n\tmeta,\n}: {\n\tcontext: ContextWithoutPersistence;\n\tmigration: Migration;\n\tmeta: PersistenceMetadata;\n}): MigrationEngine {\n\tconst newOids = new Array<ObjectIdentifier>();\n\n\tconst queries = new Proxy({} as any, {\n\t\tget() {\n\t\t\tthrow new Error(\n\t\t\t\t'Queries are not available in initial migrations; there is no database yet!',\n\t\t\t);\n\t\t},\n\t}) as any;\n\n\tconst mutations = getMigrationMutations({\n\t\tmigration,\n\t\tnewOids,\n\t\tctx: context,\n\t\tmeta,\n\t});\n\tconst engine: MigrationEngine = {\n\t\tlog: context.log,\n\t\tnewOids,\n\t\tdeleteCollection: () => {\n\t\t\tthrow new Error(\n\t\t\t\t'Calling deleteCollection() in initial migrations is not supported! Use initial migrations to seed initial data using mutations.',\n\t\t\t);\n\t\t},\n\t\tmigrate: () => {\n\t\t\tthrow new Error(\n\t\t\t\t'Calling migrate() in initial migrations is not supported! Use initial migrations to seed initial data using mutations.',\n\t\t\t);\n\t\t},\n\t\tqueries,\n\t\tmutations,\n\t\tawaitables: [],\n\t\tclose: () => Promise.resolve(),\n\t};\n\treturn engine;\n}\n", "import {\n\tdecomposeOid,\n\tgetOidRoot,\n\tMigration,\n\tMigrationEngine,\n} from '@verdant-web/common';\nimport { ContextWithoutPersistence } from '../../context/context.js';\nimport { ClientOperation, PersistenceDocumentDb } from '../interfaces.js';\nimport { PersistenceMetadata } from '../PersistenceMetadata.js';\n\nexport async function finalizeMigration({\n\tctx,\n\tdocuments,\n\tmigration,\n\tmeta,\n\tengine,\n}: {\n\tctx: ContextWithoutPersistence;\n\tdocuments: PersistenceDocumentDb;\n\tmeta: PersistenceMetadata;\n\tmigration: Migration<any>;\n\tengine: MigrationEngine;\n}) {\n\t/**\n\t * In cases where operations from the future have been\n\t * received by this client, we may have created entire\n\t * documents in metadata which were not written to storage\n\t * because all of their operations were in the future (\n\t * i.e. in the next version). We have to find those documents\n\t * and also write their snapshots to storage, because they\n\t * won't be present in storage already to 'refresh,' so\n\t * if we don't analyze metadata for 'future' operations like\n\t * this, we won't know they exist.\n\t *\n\t * This led to behavior where the metadata would be properly\n\t * synced, but after upgrading the app and migrating, items\n\t * would be missing from findAll and findOne queries.\n\t */\n\tconst docsWithUnappliedMigrations = await getDocsWithUnappliedMigrations({\n\t\tcurrentVersion: migration.oldSchema.version,\n\t\tnewVersion: migration.newSchema.version,\n\t\tctx,\n\t\tmeta,\n\t});\n\n\t// once the schema is ready, we can write back the migrated documents\n\n\tfor (const collection of migration.allCollections) {\n\t\t// map the keys to OIDs\n\t\tconst { result: oids } = await documents.findAllOids({\n\t\t\tcollection,\n\t\t});\n\t\toids.push(\n\t\t\t...engine.newOids.filter((oid) => {\n\t\t\t\treturn decomposeOid(oid).collection === collection;\n\t\t\t}),\n\t\t\t...docsWithUnappliedMigrations.filter((oid) => {\n\t\t\t\treturn decomposeOid(oid).collection === collection;\n\t\t\t}),\n\t\t);\n\n\t\tconst snapshots = await Promise.all(\n\t\t\toids.map(async (oid) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst snap = await meta.getDocumentSnapshot(oid);\n\t\t\t\t\treturn [oid, snap];\n\t\t\t\t} catch (e) {\n\t\t\t\t\t// this seems to happen with baselines/ops which are not fully\n\t\t\t\t\t// cleaned up after deletion?\n\t\t\t\t\tctx.log(\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t'Could not regenerate snapshot during migration for oid',\n\t\t\t\t\t\toid,\n\t\t\t\t\t\t'this document will not be preserved',\n\t\t\t\t\t\te,\n\t\t\t\t\t);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\n\t\tconst views: [string, any][] = snapshots.filter(\n\t\t\t(s: any): s is [string, any] => !!s,\n\t\t);\n\n\t\t// now we can write the documents back\n\t\tawait documents.saveEntities(\n\t\t\tviews.map(([oid, snapshot]) => ({\n\t\t\t\toid,\n\t\t\t\tgetSnapshot() {\n\t\t\t\t\treturn snapshot;\n\t\t\t\t},\n\t\t\t})),\n\t\t\t{\n\t\t\t\tcollections: [collection],\n\t\t\t},\n\t\t);\n\t}\n}\n\n/**\n * Gets a list of root OIDs for all documents which had operations stored already\n * that were not applied to their queryable snapshots because they were in the\n * future. These documents need to be refreshed in storage.\n */\nasync function getDocsWithUnappliedMigrations({\n\tcurrentVersion,\n\tnewVersion: _,\n\tctx,\n\tmeta,\n}: {\n\tcurrentVersion: number;\n\tnewVersion: number;\n\tctx: ContextWithoutPersistence;\n\tmeta: PersistenceMetadata;\n}) {\n\t// scan for all operations in metadata after the current version.\n\t// this could be more efficient if also filtering below or equal newVersion but\n\t// that seems so unlikely in practice...\n\tconst unappliedOperations: ClientOperation[] = [];\n\tawait meta.iterateAllOperations(\n\t\t(op) => {\n\t\t\tunappliedOperations.push(op);\n\t\t},\n\t\t{\n\t\t\tfrom: ctx.time.zeroWithVersion(currentVersion + 1),\n\t\t},\n\t);\n\treturn Array.from(\n\t\tnew Set(unappliedOperations.map((op) => getOidRoot(op.oid))),\n\t);\n}\n", "import { Migration, VerdantError } from '@verdant-web/common';\n\nexport function getMigrationPath({\n\tcurrentVersion,\n\ttargetVersion,\n\tmigrations,\n}: {\n\tcurrentVersion: number;\n\ttargetVersion: number;\n\tmigrations: Migration[];\n}) {\n\tconst path = getNextPathStep({\n\t\tcurrentVersion,\n\t\ttargetVersion,\n\t\tmigrations,\n\t});\n\tif (!path) {\n\t\tthrow new VerdantError(\n\t\t\tVerdantError.Code.MigrationPathNotFound,\n\t\t\tundefined,\n\t\t\t`No migration path found from ${currentVersion} to ${targetVersion}! This is a bug. If you're seeing this, contact the developer and provide them with the full contents of this message.`,\n\t\t);\n\t}\n\treturn path;\n}\n\nfunction getNextPathStep({\n\tcurrentVersion,\n\ttargetVersion,\n\tmigrations,\n}: {\n\tcurrentVersion: number;\n\ttargetVersion: number;\n\tmigrations: Migration[];\n}): Migration[] | null {\n\tif (currentVersion === targetVersion) {\n\t\treturn [];\n\t}\n\n\tconst fromHere = migrations\n\t\t.filter((m) => m.oldSchema.version === currentVersion)\n\t\t.sort((a, b) => b.newSchema.version - a.newSchema.version);\n\n\t// keep trying next steps, starting from the largest step,\n\t// until we find one that leads to the target version down the line\n\twhile (fromHere.length > 0) {\n\t\tconst next = fromHere.shift()!;\n\t\t// this one goes too far (probably never relevant, but still)\n\t\tif (next.newSchema.version > targetVersion) {\n\t\t\treturn null;\n\t\t}\n\t\t// exact match - we're done, return the path\n\t\tif (next.newSchema.version === targetVersion) {\n\t\t\treturn [next];\n\t\t}\n\t\t// look ahead a down the line. do we reach the target? if so,\n\t\t// we choose this path.\n\t\tconst nextPath = getNextPathStep({\n\t\t\tcurrentVersion: next.newSchema.version,\n\t\t\ttargetVersion,\n\t\t\tmigrations,\n\t\t});\n\t\tif (nextPath) {\n\t\t\treturn [next, ...nextPath];\n\t\t}\n\n\t\t// otherwise, try the next one with a smaller increment\n\t}\n\n\t// no paths from here match at all! if another layer is calling this one,\n\t// it will fallback to its next longest step. otherwise there may\n\t// be no paths at all...\n\treturn null;\n}\n", "import { Migration } from '@verdant-web/common';\nimport { ContextWithoutPersistence } from '../../context/context.js';\nimport { ShutdownHandler } from '../../context/ShutdownHandler.js';\nimport { PersistenceNamespace } from '../interfaces.js';\nimport { PersistenceMetadata } from '../PersistenceMetadata.js';\nimport { getMigrationEngine } from './engine.js';\nimport { finalizeMigration } from './finalize.js';\nimport { getMigrationPath } from './paths.js';\n\nexport async function migrate({\n\tcontext,\n\tversion,\n\tmeta,\n}: {\n\tcontext: ContextWithoutPersistence;\n\tmeta: PersistenceMetadata;\n\tversion: number;\n}) {\n\tconst ns = await context.persistence.openNamespace(\n\t\tcontext.namespace,\n\t\tcontext,\n\t);\n\tawait acquireLock(context.namespace, async () => {\n\t\tconst currentVersion = await context.persistence.getNamespaceVersion(\n\t\t\tcontext.namespace,\n\t\t);\n\n\t\tcontext.log(\n\t\t\t'debug',\n\t\t\t'Opening index database',\n\t\t\tcontext.namespace,\n\t\t\t'Current database version:',\n\t\t\tcurrentVersion,\n\t\t\t'target version:',\n\t\t\tversion,\n\t\t\tcontext.schema.wip ? '(wip)' : '',\n\t\t);\n\n\t\tconst toRun = getMigrationPath({\n\t\t\tcurrentVersion,\n\t\t\ttargetVersion: version,\n\t\t\tmigrations: context.migrations,\n\t\t});\n\n\t\tif (toRun.length > 0) {\n\t\t\tcontext.log(\n\t\t\t\t'debug',\n\t\t\t\t'Migrations to run:',\n\t\t\t\ttoRun.map((m) => m.version),\n\t\t\t);\n\t\t\tawait runMigrations({ context, ns, toRun, meta });\n\t\t}\n\t});\n}\n\nasync function acquireLock(namespace: string, procedure: () => Promise<void>) {\n\tif (typeof navigator !== 'undefined' && navigator.locks) {\n\t\tawait navigator.locks.request(`verdant_migration_${namespace}`, procedure);\n\t} else {\n\t\t// TODO: is there a fallback?\n\t\tawait procedure();\n\t}\n}\n\nexport async function runMigrations({\n\tcontext,\n\ttoRun,\n\tns,\n\tmeta,\n}: {\n\tcontext: ContextWithoutPersistence;\n\ttoRun: Migration<any>[];\n\tns: PersistenceNamespace;\n\tmeta: PersistenceMetadata;\n}) {\n\t// disable rebasing for the duration of migrations\n\tcontext.pauseRebasing = true;\n\t// now the fun part\n\tfor (const migration of toRun) {\n\t\tcontext.log(\n\t\t\t'info',\n\t\t\t`\uD83D\uDE80 Running migration v${migration.oldSchema.version} -> v${migration.newSchema.version}`,\n\t\t);\n\t\tconst migrationContext = context.cloneWithOptions({\n\t\t\tschema: migration.oldSchema,\n\t\t\tpersistenceShutdownHandler: new ShutdownHandler(context.log),\n\t\t});\n\t\t// this will only write to our metadata store via operations!\n\t\tconst engine = await getMigrationEngine({\n\t\t\tmigration,\n\t\t\tcontext: migrationContext,\n\t\t\tns,\n\t\t\tmeta,\n\t\t});\n\t\ttry {\n\t\t\tcontext.log(\n\t\t\t\t'debug',\n\t\t\t\t'Migrating data',\n\t\t\t\tmigrationContext.namespace,\n\t\t\t\t'from version',\n\t\t\t\tmigration.oldSchema.version,\n\t\t\t\t'to version',\n\t\t\t\tmigration.newSchema.version,\n\t\t\t);\n\t\t\tawait migration.migrate(engine);\n\t\t\tcontext.log('debug', 'Awaiting remaining migration tasks');\n\t\t\t// wait on any out-of-band async operations to complete\n\t\t\tawait Promise.all(engine.awaitables);\n\t\t} catch (err) {\n\t\t\tcontext.log(\n\t\t\t\t'critical',\n\t\t\t\t`Migration failed (${migration.oldSchema.version} -> ${migration.newSchema.version})`,\n\t\t\t\terr,\n\t\t\t);\n\t\t\tif (err instanceof Error) {\n\t\t\t\tthrow err;\n\t\t\t} else {\n\t\t\t\tthrow new Error('Unknown error during migration');\n\t\t\t}\n\t\t}\n\n\t\tawait engine.close();\n\n\t\tmigrationContext.log(\n\t\t\t'debug',\n\t\t\t'Upgrading database',\n\t\t\tmigrationContext.namespace,\n\t\t\t'from version',\n\t\t\tmigrationContext.schema.version,\n\t\t\t'to version',\n\t\t\tmigration.newSchema.version,\n\t\t);\n\n\t\tawait ns.applyMigration(migrationContext, migration);\n\n\t\t// switch to the new schema\n\t\tmigrationContext.schema = migration.newSchema;\n\t\tconst upgradedDocuments = await ns.openDocuments(migrationContext);\n\n\t\tawait finalizeMigration({\n\t\t\tctx: migrationContext,\n\t\t\tmigration,\n\t\t\tengine,\n\t\t\tdocuments: upgradedDocuments,\n\t\t\tmeta,\n\t\t});\n\t\tawait upgradedDocuments.close();\n\n\t\tmigrationContext.log(\n\t\t\t'debug',\n\t\t\t`Migration of ${migrationContext.namespace} complete.`,\n\t\t);\n\t\tmigrationContext.log(\n\t\t\t'info',\n\t\t\t`\n\t\t\t\t\u2B06\uFE0F v${migration.newSchema.version} Migration complete. Here's the rundown:\n\t\t\t\t\t- Added collections: ${migration.addedCollections.join(', ')}\n\t\t\t\t\t- Removed collections: ${migration.removedCollections.join(', ')}\n\t\t\t\t\t- Changed collections: ${migration.changedCollections.join(', ')}\n\t\t\t\t\t- New indexes: ${Object.keys(migration.addedIndexes)\n\t\t\t\t\t\t.map((col) =>\n\t\t\t\t\t\t\tmigration.addedIndexes[col].map((i) => `${col}.${i.name}`),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.flatMap((i) => i)\n\t\t\t\t\t\t.join(', ')}\n\t\t\t\t\t- Removed indexes: ${Object.keys(migration.removedIndexes)\n\t\t\t\t\t\t.map((col) =>\n\t\t\t\t\t\t\tmigration.removedIndexes[col].map((i) => `${col}.${i.name}`),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.flatMap((i) => i)\n\t\t\t\t\t\t.join(', ')}\n\t\t\t`,\n\t\t);\n\t}\n\tcontext.pauseRebasing = false;\n}\n", "import { FileData, FileRef } from '@verdant-web/common';\nimport { Context, FileConfig } from '../context/context.js';\nimport { PersistedFileData, PersistenceFileDb } from './interfaces.js';\n\nexport class PersistenceFiles {\n\tconstructor(\n\t\tprivate db: PersistenceFileDb,\n\t\tprivate context: Omit<Context, 'queries'>,\n\t) {\n\t\tcontext.internalEvents.subscribe('filesDeleted', this.onFileRefsDeleted);\n\t\t// on startup, try deleting old files.\n\t\tthis.cleanupDeletedFiles();\n\t}\n\n\tprivate get config(): Required<FileConfig> {\n\t\treturn {\n\t\t\tcanCleanupDeletedFile(fileData) {\n\t\t\t\treturn (\n\t\t\t\t\tfileData.deletedAt !== null &&\n\t\t\t\t\tfileData.deletedAt < Date.now() - 1000 * 60 * 24 * 3\n\t\t\t\t);\n\t\t\t},\n\t\t\t...this.context.config.files,\n\t\t};\n\t}\n\n\tonServerReset = (since: string | null) =>\n\t\tthis.db.resetSyncedStatusSince(since);\n\t/**\n\t * Adds a file to persistence.\n\t * Optionally download and re-upload remote files to create a new copy.\n\t */\n\tadd = async (file: FileData, options?: { cloneRemote?: boolean }) => {\n\t\t// this method accepts a FileData which refers to a remote\n\t\t// file, as well as local files. in the case of a remote file,\n\t\t// we actually re-download and upload the file again. this powers\n\t\t// the cloning of documents with files; we clone their filedata\n\t\t// and re-upload to a new file ID. otherwise, when the cloned\n\t\t// filedata was marked deleted, the original file would be deleted\n\t\t// and the clone would refer to a missing file.\n\t\tif (file.url && !(file.localPath || file.file) && options?.cloneRemote) {\n\t\t\tthis.context.log(\n\t\t\t\t'debug',\n\t\t\t\t'Cloning remote file added to a new entity. Downloading remote file...',\n\t\t\t\tfile.id,\n\t\t\t);\n\t\t\tconst blob = await this.loadFileContents(file, 0, 3);\n\t\t\t// convert blob to file with name and type\n\t\t\tfile.file = new File([blob], file.name, { type: file.type });\n\t\t\t// remove the URL - it points to the original file's uploaded server version,\n\t\t\t// but this file is a clone\n\t\t\tdelete file.url;\n\t\t\tthis.context.log(\n\t\t\t\t'debug',\n\t\t\t\t'Downloaded remote file',\n\t\t\t\tfile.id,\n\t\t\t\tfile.name,\n\t\t\t\t'. Cleared its remote URL.',\n\t\t\t);\n\t\t} else if (!file.url && !file.file && !file.localPath) {\n\t\t\tthis.context.log(\n\t\t\t\t'warn',\n\t\t\t\t'File added without a file or URL. This file will not be available for use.',\n\t\t\t\tfile.id,\n\t\t\t);\n\t\t}\n\n\t\t// always reset remote status to false, this is a new file just created\n\t\t// and must be uploaded, even if it is cloned from an uploaded file.\n\t\tfile.remote = false;\n\n\t\t// store in persistence db\n\t\tthis.context.log('debug', 'Adding file to persistence', file);\n\t\tawait this.db.add(file);\n\t\t// fire event for sync to pick up and upload the file\n\t\tthis.context.internalEvents.emit('fileAdded', file);\n\t\tthis.context.globalEvents.emit('fileSaved', file);\n\t\tthis.context.log(\n\t\t\t'debug',\n\t\t\t'File added',\n\t\t\tfile.id,\n\t\t\tfile.name,\n\t\t\tfile.type,\n\t\t\tfile.file\n\t\t\t\t? 'with binary file'\n\t\t\t\t: file.url\n\t\t\t\t\t? 'with url'\n\t\t\t\t\t: file.localPath\n\t\t\t\t\t\t? 'with local path'\n\t\t\t\t\t\t: 'with no data',\n\t\t);\n\t\treturn file;\n\t};\n\tupdate = async (file: FileData) => {\n\t\tawait this.db.add(file);\n\t\tthis.context.globalEvents.emit('fileSaved', file);\n\t\tthis.context.log('debug', 'File updated', file.id, file.name);\n\t};\n\tonUploaded = this.db.markUploaded.bind(this.db);\n\tget = this.db.get.bind(this.db);\n\tgetAll = this.db.getAll.bind(this.db);\n\tlistUnsynced = this.db.listUnsynced.bind(this.db);\n\titerateOverPendingDelete = this.db.iterateOverPendingDelete.bind(this.db);\n\tstats = this.db.stats.bind(this.db);\n\n\tprivate getFileExportName = (originalFileName: string, id: string) => {\n\t\treturn `${id}___${originalFileName}`;\n\t};\n\texport = async (downloadRemote = true) => {\n\t\tconst storedFiles = await this.getAll();\n\t\tif (downloadRemote) {\n\t\t\tfor (const storedFile of storedFiles) {\n\t\t\t\t// if it doesn't have a buffer, we need to read one from the server\n\t\t\t\tif (!storedFile.file && (storedFile.url || storedFile.localPath)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst blob = await this.loadFileContents(storedFile);\n\t\t\t\t\t\tstoredFile.file = blob;\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tthis.context.log(\n\t\t\t\t\t\t\t'error',\n\t\t\t\t\t\t\t\"Failed to download file to cache it locally. The file will still be available using its URL. Check the file server's CORS configuration.\",\n\t\t\t\t\t\t\tstoredFile,\n\t\t\t\t\t\t\terr,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else if (!storedFile.file) {\n\t\t\t\t\tthis.context.log(\n\t\t\t\t\t\t'warn',\n\t\t\t\t\t\t`File ${storedFile.id} has no file or URL. It will be missing in the export.`,\n\t\t\t\t\t\tstoredFile,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// split files into data and files\n\t\tconst fileData: Array<Omit<PersistedFileData, 'file'>> = [];\n\t\tconst files: Array<File> = [];\n\n\t\tfor (const fileExport of storedFiles) {\n\t\t\tconst file = fileExport.file;\n\t\t\tdelete fileExport.file;\n\t\t\tfileData.push(fileExport);\n\t\t\tif (file) {\n\t\t\t\t// rename with ID\n\t\t\t\tconst asFile = new File(\n\t\t\t\t\t[file],\n\t\t\t\t\tthis.getFileExportName(fileExport.name, fileExport.id),\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: fileExport.type,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tfiles.push(asFile);\n\t\t\t} else {\n\t\t\t\tthis.context.log(\n\t\t\t\t\t'warn',\n\t\t\t\t\t`File ${fileExport.id} was could not be loaded locally or from the server. It will be missing in the export.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tfileData,\n\t\t\tfiles,\n\t\t};\n\t};\n\n\timport = async ({\n\t\tfileData,\n\t\tfiles,\n\t}: {\n\t\tfileData: Array<Omit<PersistedFileData, 'file'>>;\n\t\tfiles: File[];\n\t}) => {\n\t\t// re-attach files to their file data and import\n\t\tconst fileToIdMap = new Map(\n\t\t\tfiles.map((file) => {\n\t\t\t\tconst { id } = this.parseFileExportname(file.name);\n\t\t\t\treturn [id, file];\n\t\t\t}),\n\t\t);\n\t\tconst importedFiles: PersistedFileData[] = fileData.map((fileData) => {\n\t\t\tconst file = fileToIdMap.get(fileData.id);\n\n\t\t\tif (!file) {\n\t\t\t\tthis.context.log('warn', `File ${fileData.id} was not found in import`);\n\t\t\t\treturn fileData;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\t...fileData,\n\t\t\t\tfile,\n\t\t\t};\n\t\t});\n\t\tawait Promise.all(importedFiles.map((file) => this.add(file)));\n\t};\n\n\tprivate parseFileExportname = (name: string) => {\n\t\tconst [id, originalFileName] = name.split('___');\n\t\treturn { id, originalFileName };\n\t};\n\n\tprivate loadFileContents = async (\n\t\tfile: FileData,\n\t\tretries = 0,\n\t\tmaxRetries = 0,\n\t) => {\n\t\ttry {\n\t\t\treturn await this.db.loadFileContents(file, this.context);\n\t\t} catch (err) {\n\t\t\tif (retries < maxRetries) {\n\t\t\t\treturn new Promise<Blob>((resolve, reject) => {\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis.loadFileContents(file, retries + 1, maxRetries).then(\n\t\t\t\t\t\t\tresolve,\n\t\t\t\t\t\t\treject,\n\t\t\t\t\t\t);\n\t\t\t\t\t}, 1000);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.context.log(\n\t\t\t\t\t'error',\n\t\t\t\t\t`Failed to download file after ${maxRetries} retries`,\n\t\t\t\t\terr,\n\t\t\t\t);\n\t\t\t\tthrow new Error(`Failed to download file after ${maxRetries} retries`, {\n\t\t\t\t\tcause: err,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\n\tcleanupDeletedFiles = async () => {\n\t\tlet count = 0;\n\t\tlet skipCount = 0;\n\t\tconst deletable: string[] = [];\n\t\tawait this.iterateOverPendingDelete((fileData) => {\n\t\t\tif (this.config.canCleanupDeletedFile(fileData)) {\n\t\t\t\tcount++;\n\t\t\t\tdeletable.push(fileData.id);\n\t\t\t} else {\n\t\t\t\tskipCount++;\n\t\t\t}\n\t\t});\n\t\tfor (const id of deletable) {\n\t\t\tawait this.db.delete(id);\n\t\t}\n\n\t\tthis.context.log(\n\t\t\t'info',\n\t\t\t`Cleaned up ${count} files, skipped ${skipCount} files`,\n\t\t);\n\t};\n\n\tprivate onFileRefsDeleted = async (fileRefs: FileRef[]) => {\n\t\tawait Promise.all(\n\t\t\tfileRefs.map(async (fileRef) => {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.db.markPendingDelete(fileRef.id);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthis.context.log('error', 'Failed to mark file for deletion', err);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t\tthis.context.log(\n\t\t\t'info',\n\t\t\t`Marked ${fileRefs.length} files as pending delete`,\n\t\t);\n\t};\n}\n", "import {\n\tapplyPatch,\n\tassert,\n\tassignOid,\n\tDocumentBaseline,\n\tgetOidRoot,\n\tObjectIdentifier,\n\tOperation,\n\tsubstituteRefsWithObjects,\n} from '@verdant-web/common';\nimport cuid from 'cuid';\nimport { ContextWithoutPersistence } from '../context/context.js';\nimport {\n\tAbstractTransaction,\n\tClientOperation,\n\tCommonQueryOptions,\n\tLocalReplicaInfo,\n\tMetadataExport,\n\tPersistenceMetadataDb,\n} from './interfaces.js';\nimport { MessageCreator } from './MessageCreator.js';\nimport { PersistenceRebaser } from './PersistenceRebaser.js';\n\nexport class PersistenceMetadata {\n\tprivate rebaser: PersistenceRebaser;\n\t/** Available to others, like sync... */\n\treadonly messageCreator: MessageCreator;\n\n\tconstructor(\n\t\tprivate db: PersistenceMetadataDb,\n\t\tprivate ctx: ContextWithoutPersistence,\n\t) {\n\t\tthis.rebaser = new PersistenceRebaser(db, this, ctx);\n\t\tthis.messageCreator = new MessageCreator(db, this, ctx);\n\t}\n\n\tprivate insertOperations = async (\n\t\toperations: ClientOperation[],\n\t\toptions?: { transaction?: AbstractTransaction },\n\t) => {\n\t\tthis.ctx.log(\n\t\t\t'debug',\n\t\t\t`Inserting ${operations.length} operations`,\n\t\t\toperations,\n\t\t);\n\n\t\tconst affectedDocumentOids = await this.db.addOperations(\n\t\t\toperations,\n\t\t\toptions,\n\t\t);\n\n\t\tfor (const op of operations) {\n\t\t\tthis.ctx.globalEvents.emit('operation', op);\n\t\t}\n\n\t\t// we can now enqueue and check for rebase opportunities\n\t\tif (\n\t\t\t!this.ctx.config.persistence?.disableRebasing &&\n\t\t\t!this.ctx.pauseRebasing\n\t\t) {\n\t\t\tthis.rebaser.tryAutonomousRebase();\n\t\t}\n\n\t\treturn affectedDocumentOids;\n\t};\n\n\tprivate insertLocalOperations = async (\n\t\toperations: Operation[],\n\t\toptions?: { transaction?: AbstractTransaction },\n\t) => {\n\t\tif (operations.length === 0) return;\n\n\t\t// add local flag, in place.\n\t\tfor (const operation of operations) {\n\t\t\t(operation as ClientOperation).isLocal = true;\n\t\t}\n\t\tawait this.insertOperations(operations as ClientOperation[], options);\n\t\tthis.ctx.log(\n\t\t\t'debug',\n\t\t\t`Inserted ${operations.length} local operations; sending sync message`,\n\t\t);\n\t\tconst message = await this.messageCreator.createOperation({ operations });\n\t\tthis.ctx.internalEvents.emit('outgoingSyncMessage', message);\n\t};\n\n\tprivate insertRemoteOperations = async (\n\t\toperations: Operation[],\n\t\toptions?: { transaction?: AbstractTransaction },\n\t) => {\n\t\tif (operations.length === 0) return [];\n\n\t\t// add local flag, in place\n\t\tfor (const operation of operations) {\n\t\t\t(operation as ClientOperation).isLocal = false;\n\t\t}\n\n\t\tawait this.insertOperations(operations as ClientOperation[], options);\n\n\t\tthis.ack(operations[operations.length - 1].timestamp);\n\t};\n\n\tprivate insertRemoteBaselines = async (\n\t\tbaselines: DocumentBaseline[],\n\t\toptions?: { transaction?: AbstractTransaction },\n\t) => {\n\t\tif (baselines.length === 0) return [];\n\t\tthis.ctx.log('debug', `Inserting ${baselines.length} remote baselines`);\n\n\t\tawait this.db.setBaselines(baselines, options);\n\n\t\t// this.ack(baselines[baselines.length - 1].timestamp);\n\n\t\tconst affectedOidSet = new Set<ObjectIdentifier>();\n\t\tbaselines.forEach((baseline) => {\n\t\t\taffectedOidSet.add(getOidRoot(baseline.oid));\n\t\t});\n\n\t\treturn Array.from(affectedOidSet);\n\t};\n\n\tdeleteDocument = async (rootOid: string) => {\n\t\tconst oids = new Set<ObjectIdentifier>();\n\t\tconst documentOid = getOidRoot(rootOid);\n\t\tassert(documentOid === rootOid, 'Must be root document OID');\n\t\toids.add(documentOid);\n\t\t// readwrite mode to block on other write transactions\n\t\treturn this.db.transaction(\n\t\t\t{\n\t\t\t\tstoreNames: ['baselines', 'operations'],\n\t\t\t},\n\t\t\tasync (transaction) => {\n\t\t\t\tawait Promise.all([\n\t\t\t\t\tthis.db.iterateDocumentBaselines(\n\t\t\t\t\t\tdocumentOid,\n\t\t\t\t\t\t(baseline) => {\n\t\t\t\t\t\t\toids.add(baseline.oid);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ transaction },\n\t\t\t\t\t),\n\t\t\t\t\tthis.db.iterateDocumentOperations(\n\t\t\t\t\t\tdocumentOid,\n\t\t\t\t\t\t(patch) => {\n\t\t\t\t\t\t\toids.add(patch.oid);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ transaction },\n\t\t\t\t\t),\n\t\t\t\t]);\n\t\t\t\tconst authz = await this.getDocumentAuthz(documentOid);\n\t\t\t\tconst ops = new Array<Operation>();\n\t\t\t\tfor (const oid of oids) {\n\t\t\t\t\tops.push({\n\t\t\t\t\t\toid,\n\t\t\t\t\t\ttimestamp: this.ctx.time.now,\n\t\t\t\t\t\tdata: { op: 'delete' },\n\t\t\t\t\t\tauthz,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this.insertLocalOperations(ops, { transaction });\n\t\t\t},\n\t\t);\n\t};\n\n\tdeleteCollection = async (collection: string) => {\n\t\tconst oids = new Set<ObjectIdentifier>();\n\t\treturn this.db.transaction(\n\t\t\t{\n\t\t\t\tstoreNames: ['baselines', 'operations'],\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t\tasync (transaction) => {\n\t\t\t\tawait Promise.all([\n\t\t\t\t\tthis.db.iterateCollectionBaselines(\n\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t(baseline) => {\n\t\t\t\t\t\t\toids.add(baseline.oid);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ transaction },\n\t\t\t\t\t),\n\t\t\t\t\tthis.db.iterateCollectionOperations(\n\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t(patch) => {\n\t\t\t\t\t\t\toids.add(patch.oid);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ transaction },\n\t\t\t\t\t),\n\t\t\t\t]);\n\n\t\t\t\tconst ops = new Array<Operation>();\n\t\t\t\tfor (const oid of oids) {\n\t\t\t\t\tops.push({\n\t\t\t\t\t\toid,\n\t\t\t\t\t\ttimestamp: this.ctx.time.now,\n\t\t\t\t\t\tdata: { op: 'delete' },\n\t\t\t\t\t\tauthz: undefined,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn this.insertLocalOperations(ops, { transaction });\n\t\t\t},\n\t\t);\n\t};\n\n\tgetDocumentSnapshot = async (\n\t\toid: ObjectIdentifier,\n\t\toptions: { to?: string } = {},\n\t) => {\n\t\tconst documentOid = getOidRoot(oid);\n\t\tassert(documentOid === oid, 'Must be root document OID');\n\t\treturn this.db.transaction(\n\t\t\t{\n\t\t\t\tstoreNames: ['baselines', 'operations'],\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t\tasync (transaction) => {\n\t\t\t\tconst baselines: DocumentBaseline[] = [];\n\t\t\t\tawait this.db.iterateDocumentBaselines(\n\t\t\t\t\tdocumentOid,\n\t\t\t\t\t(b) => {\n\t\t\t\t\t\tbaselines.push(b);\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttransaction,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tconst objectMap = new Map<ObjectIdentifier, any>();\n\t\t\t\tfor (const baseline of baselines) {\n\t\t\t\t\tif (baseline.snapshot) {\n\t\t\t\t\t\tassignOid(baseline.snapshot, baseline.oid);\n\t\t\t\t\t}\n\t\t\t\t\tobjectMap.set(baseline.oid, baseline.snapshot);\n\t\t\t\t}\n\t\t\t\tawait this.db.iterateDocumentOperations(\n\t\t\t\t\tdocumentOid,\n\t\t\t\t\t(op) => {\n\t\t\t\t\t\tconst obj = objectMap.get(op.oid) || undefined;\n\t\t\t\t\t\tconst newObj = applyPatch(obj, op.data);\n\t\t\t\t\t\tif (newObj) {\n\t\t\t\t\t\t\tassignOid(newObj, op.oid);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tobjectMap.set(op.oid, newObj);\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttransaction,\n\t\t\t\t\t\t// only apply operations up to the current time\n\t\t\t\t\t\tto: options.to || this.ctx.time.now,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tconst root = objectMap.get(documentOid);\n\t\t\t\tif (root) {\n\t\t\t\t\tsubstituteRefsWithObjects(root, objectMap);\n\t\t\t\t}\n\t\t\t\treturn root;\n\t\t\t},\n\t\t);\n\t};\n\n\tgetDocumentData = async (\n\t\toid: ObjectIdentifier,\n\t\toptions?: { abort?: AbortSignal },\n\t) => {\n\t\treturn this.db.transaction(\n\t\t\t{\n\t\t\t\tstoreNames: ['baselines', 'operations'],\n\t\t\t\tabort: options?.abort,\n\t\t\t},\n\t\t\tasync (transaction) => {\n\t\t\t\tconst baselines: DocumentBaseline[] = [];\n\t\t\t\tconst operations: Record<ObjectIdentifier, Operation[]> = {};\n\t\t\t\tawait Promise.all([\n\t\t\t\t\tthis.db.iterateDocumentBaselines(\n\t\t\t\t\t\toid,\n\t\t\t\t\t\t(baseline) => {\n\t\t\t\t\t\t\tbaselines.push(baseline);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttransaction,\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t\tthis.db.iterateDocumentOperations(\n\t\t\t\t\t\toid,\n\t\t\t\t\t\t(op) => {\n\t\t\t\t\t\t\toperations[op.oid] ??= [];\n\t\t\t\t\t\t\toperations[op.oid].push(op);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ transaction },\n\t\t\t\t\t),\n\t\t\t\t]);\n\t\t\t\treturn {\n\t\t\t\t\tbaselines,\n\t\t\t\t\toperations,\n\t\t\t\t};\n\t\t\t},\n\t\t);\n\t};\n\n\tgetDocumentAuthz = async (oid: ObjectIdentifier) => {\n\t\tlet authz;\n\t\tawait this.db.iterateEntityOperations(oid, (op) => {\n\t\t\tif (op.data.op === 'initialize') {\n\t\t\t\tauthz = op.authz;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t});\n\t\treturn authz;\n\t};\n\n\tinsertData = async (\n\t\tdata: {\n\t\t\tbaselines?: DocumentBaseline[];\n\t\t\toperations?: Operation[];\n\t\t\tisLocal?: boolean;\n\t\t},\n\t\toptions?: { abort?: AbortSignal },\n\t) => {\n\t\treturn this.db.transaction(\n\t\t\t{\n\t\t\t\tstoreNames: ['baselines', 'operations'],\n\t\t\t\tabort: options?.abort,\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t\tasync (transaction) => {\n\t\t\t\tthis.ctx.log('debug', 'Begin insert data transaction');\n\t\t\t\tif (data.baselines) {\n\t\t\t\t\tawait this.insertRemoteBaselines(data.baselines, { transaction });\n\t\t\t\t}\n\t\t\t\tthis.ctx.log('debug', 'Inserted baselines (if any)');\n\t\t\t\tif (options?.abort?.aborted) throw new Error('Aborted');\n\t\t\t\tif (data.operations) {\n\t\t\t\t\tif (data.isLocal) {\n\t\t\t\t\t\tthis.ctx.log('debug', 'Inserting local operations');\n\t\t\t\t\t\tawait this.insertLocalOperations(data.operations, { transaction });\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.ctx.log('debug', 'Inserting remote operations');\n\t\t\t\t\t\tawait this.insertRemoteOperations(data.operations, { transaction });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.ctx.log('debug', 'End insert data transaction');\n\t\t\t},\n\t\t);\n\t};\n\n\tupdateLastSynced = async (timestamp: string) => {\n\t\tif (this.ctx.closing) return;\n\n\t\treturn this.updateLocalReplica({\n\t\t\tlastSyncedLogicalTime: timestamp,\n\t\t});\n\t};\n\tsetGlobalAck = async (ack: string) => {\n\t\tif (this.ctx.closing) return;\n\t\tawait this.db.setGlobalAck(ack);\n\t\tif (!this.ctx.config.persistence?.disableRebasing) {\n\t\t\tawait this.rebaser.scheduleRebase(ack);\n\t\t}\n\t};\n\n\t// caching local replica as it's accessed often and only changed\n\t// via this class.\n\tprivate _cachedLocalReplica: LocalReplicaInfo | null = null;\n\tprivate _creatingLocalReplica: Promise<LocalReplicaInfo> | undefined =\n\t\tundefined;\n\tgetLocalReplica = async (\n\t\toptions?: CommonQueryOptions,\n\t): Promise<LocalReplicaInfo> => {\n\t\tif (this._cachedLocalReplica) return this._cachedLocalReplica;\n\n\t\tconst lookup = await this.db.getLocalReplica(options);\n\t\tif (lookup) {\n\t\t\tthis.ctx.log('debug', 'Read local replica', lookup);\n\t\t\tthis._cachedLocalReplica = lookup;\n\t\t\treturn lookup;\n\t\t}\n\n\t\tif (this._creatingLocalReplica) {\n\t\t\treturn this._creatingLocalReplica;\n\t\t}\n\n\t\tthis._creatingLocalReplica = (async () => {\n\t\t\tconst replicaId = cuid();\n\t\t\tconst replicaInfo: LocalReplicaInfo = {\n\t\t\t\tid: replicaId,\n\t\t\t\tuserId: null,\n\t\t\t\tackedLogicalTime: null,\n\t\t\t\tlastSyncedLogicalTime: null,\n\t\t\t};\n\t\t\tawait this.db.updateLocalReplica(replicaInfo);\n\t\t\tthis._cachedLocalReplica = replicaInfo;\n\t\t\treturn replicaInfo;\n\t\t})();\n\t\treturn this._creatingLocalReplica;\n\t};\n\tupdateLocalReplica = async (\n\t\tdata: Partial<LocalReplicaInfo>,\n\t\topts?: { transaction?: AbstractTransaction },\n\t) => {\n\t\tconst original = await this.getLocalReplica(opts);\n\t\tassert(!!original, 'Local replica must exist');\n\t\tObject.assign(original, data);\n\t\tthis._cachedLocalReplica = original;\n\t\tawait this.db.updateLocalReplica(original, opts);\n\t};\n\n\t// used to construct sync messages\n\titerateLocalOperations = this.db.iterateLocalOperations;\n\titerateAllOperations = this.db.iterateAllOperations;\n\titerateAllBaselines = this.db.iterateAllBaselines;\n\n\treset = async () => {\n\t\tif (this.ctx.closing) return;\n\t\tawait this.db.reset();\n\t};\n\tstats = this.db.stats;\n\n\texport = async (): Promise<MetadataExport> => {\n\t\tconst baselines = new Array<DocumentBaseline>();\n\t\tconst operations = new Array<ClientOperation>();\n\t\treturn this.db.transaction(\n\t\t\t{\n\t\t\t\tstoreNames: ['baselines', 'operations'],\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t\tasync (transaction) => {\n\t\t\t\tawait this.iterateAllOperations(\n\t\t\t\t\t(op) => {\n\t\t\t\t\t\toperations.push(op);\n\t\t\t\t\t},\n\t\t\t\t\t{ transaction },\n\t\t\t\t);\n\t\t\t\tawait this.iterateAllBaselines(\n\t\t\t\t\t(baseline) => {\n\t\t\t\t\t\tbaselines.push(baseline);\n\t\t\t\t\t},\n\t\t\t\t\t{ transaction },\n\t\t\t\t);\n\t\t\t\tconst localReplica = await this.getLocalReplica();\n\t\t\t\treturn {\n\t\t\t\t\toperations,\n\t\t\t\t\tbaselines,\n\t\t\t\t\tlocalReplica,\n\t\t\t\t\tschemaVersion: this.ctx.schema.version,\n\t\t\t\t};\n\t\t\t},\n\t\t);\n\t};\n\n\tresetFrom = async (data: MetadataExport) => {\n\t\tthis._cachedLocalReplica = null;\n\n\t\t// await this.db.transaction(\n\t\t// \t{ mode: 'readwrite', storeNames: ['baselines', 'operations', 'info'] },\n\t\t// \tasync (tx) => {\n\t\t// \t\tawait this.db.reset({ clearReplica: true, transaction: tx });\n\n\t\t// \t\tif (data.localReplica) {\n\t\t// \t\t\tawait this.updateLocalReplica(\n\t\t// \t\t\t\t{\n\t\t// \t\t\t\t\tackedLogicalTime: data.localReplica.ackedLogicalTime,\n\t\t// \t\t\t\t\tlastSyncedLogicalTime: data.localReplica.lastSyncedLogicalTime,\n\t\t// \t\t\t\t},\n\t\t// \t\t\t\t{\n\t\t// \t\t\t\t\ttransaction: tx,\n\t\t// \t\t\t\t},\n\t\t// \t\t\t);\n\t\t// \t\t}\n\t\t// \t},\n\t\t// );\n\n\t\t// transaction wasn't working for IDB (invalid state -- it was closing early?)\n\t\tawait this.db.reset({ clearReplica: true });\n\n\t\tif (data.localReplica) {\n\t\t\tawait this.updateLocalReplica({\n\t\t\t\tackedLogicalTime: data.localReplica.ackedLogicalTime,\n\t\t\t\tlastSyncedLogicalTime: data.localReplica.lastSyncedLogicalTime,\n\t\t\t});\n\t\t}\n\t\t// after transaction completes, insert new data.\n\t\t// TODO: does this have to be split up like this?\n\t\tthis.ctx.log('debug', 'Resetting metadata from export', data);\n\t\tawait this.insertData({\n\t\t\toperations: data.operations,\n\t\t\tbaselines: data.baselines,\n\t\t\tisLocal: true,\n\t\t});\n\t};\n\n\tmanualRebase = async () => {\n\t\tif (this.ctx.closing || this.ctx.config.persistence?.disableRebasing)\n\t\t\treturn;\n\t\tconst ackInfo = await this.db.getAckInfo();\n\t\tif (ackInfo.globalAckTimestamp) {\n\t\t\tawait this.rebaser.scheduleRebase(ackInfo.globalAckTimestamp);\n\t\t}\n\t};\n\n\tprivate ack = async (timestamp: string) => {\n\t\tconst localReplicaInfo = await this.getLocalReplica();\n\t\t// can't ack timestamps from the future.\n\t\tif (timestamp > this.ctx.time.now) return;\n\n\t\tthis.ctx.internalEvents.emit('outgoingSyncMessage', {\n\t\t\ttype: 'ack',\n\t\t\treplicaId: localReplicaInfo.id,\n\t\t\ttimestamp,\n\t\t});\n\n\t\tif (\n\t\t\t!this.ctx.closing &&\n\t\t\t(!localReplicaInfo.ackedLogicalTime ||\n\t\t\t\ttimestamp > localReplicaInfo.ackedLogicalTime)\n\t\t) {\n\t\t\tthis.updateLocalReplica({ ackedLogicalTime: timestamp });\n\t\t}\n\t};\n}\n", "import {\n\tAckMessage,\n\tDisconnectingMessage,\n\tDocumentBaseline,\n\tgetOidRoot,\n\tHeartbeatMessage,\n\tObjectIdentifier,\n\tOperation,\n\tOperationMessage,\n\tpickValidOperationKeys,\n\tPresenceUpdateMessage,\n\tSyncMessage,\n\tVerdantInternalPresence,\n} from '@verdant-web/common';\n\nimport { Context } from '../context/context.js';\nimport { PersistenceMetadataDb } from './interfaces.js';\nimport type { PersistenceMetadata } from './PersistenceMetadata.js';\n\nexport class MessageCreator {\n\tconstructor(\n\t\tprivate db: PersistenceMetadataDb,\n\t\tprivate meta: PersistenceMetadata,\n\t\tprivate ctx: Pick<Context, 'time' | 'schema' | 'log'>,\n\t) {}\n\n\tcreateOperation = async (\n\t\tinit: Pick<OperationMessage, 'operations'> & {\n\t\t\ttimestamp?: string;\n\t\t},\n\t): Promise<OperationMessage> => {\n\t\tconst localInfo = await this.meta.getLocalReplica();\n\t\tthis.ctx.log('debug', 'Creating operation message', init.operations.length);\n\t\treturn {\n\t\t\ttype: 'op',\n\t\t\ttimestamp: this.ctx.time.now,\n\t\t\treplicaId: localInfo.id,\n\t\t\toperations: init.operations.map(pickValidOperationKeys),\n\t\t};\n\t};\n\n\t/**\n\t * @param since - override local understanding of last sync time\n\t */\n\tcreateSyncStep1 = async (since?: string | null): Promise<SyncMessage> => {\n\t\tconst localReplicaInfo = await this.meta.getLocalReplica();\n\n\t\tconst provideChangesSince =\n\t\t\tsince === null ? null : localReplicaInfo.lastSyncedLogicalTime;\n\n\t\t// collect all of our operations that are newer than the server's last operation\n\t\t// if server replica isn't stored, we're syncing for the first time.\n\t\tconst operations: Operation[] = [];\n\t\tconst affectedDocs = new Set<ObjectIdentifier>();\n\n\t\treturn this.db.transaction(\n\t\t\t{\n\t\t\t\tmode: 'readwrite',\n\t\t\t\tstoreNames: ['operations', 'baselines'],\n\t\t\t},\n\t\t\tasync (tx) => {\n\t\t\t\t// FIXME: this branch gives bad vibes. should we always\n\t\t\t\t// send all operations from other replicas too? is there\n\t\t\t\t// ever a case where we have a \"since\" timestamp and there\n\t\t\t\t// are foreign ops that match it?\n\t\t\t\tif (provideChangesSince) {\n\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t'debug',\n\t\t\t\t\t\t'Syncing local operations since',\n\t\t\t\t\t\tprovideChangesSince,\n\t\t\t\t\t);\n\t\t\t\t\tawait this.db.iterateLocalOperations(\n\t\t\t\t\t\t(patch) => {\n\t\t\t\t\t\t\toperations.push(pickValidOperationKeys(patch));\n\t\t\t\t\t\t\taffectedDocs.add(getOidRoot(patch.oid));\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tafter: provideChangesSince,\n\t\t\t\t\t\t\t// block on writes to prevent race conditions\n\t\t\t\t\t\t\ttransaction: tx,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthis.ctx.log('debug', 'Syncing all operations');\n\t\t\t\t\t// if providing the whole history, don't limit to only local\n\t\t\t\t\t// operations\n\t\t\t\t\tawait this.db.iterateAllOperations(\n\t\t\t\t\t\t(patch) => {\n\t\t\t\t\t\t\toperations.push(pickValidOperationKeys(patch));\n\t\t\t\t\t\t\taffectedDocs.add(getOidRoot(patch.oid));\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttransaction: tx,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// we only need to send baselines if we've never synced before\n\t\t\t\tlet baselines: DocumentBaseline[] = [];\n\t\t\t\tif (!provideChangesSince) {\n\t\t\t\t\tawait this.db.iterateAllBaselines(\n\t\t\t\t\t\t(b) => {\n\t\t\t\t\t\t\tbaselines.push(b);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttransaction: tx,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (operations.length > 0) {\n\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t'debug',\n\t\t\t\t\t\t`Syncing ${operations.length} operations since ${provideChangesSince}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'sync',\n\t\t\t\t\tschemaVersion: this.ctx.schema.version,\n\t\t\t\t\ttimestamp: this.ctx.time.now,\n\t\t\t\t\treplicaId: localReplicaInfo.id,\n\t\t\t\t\tresyncAll: !localReplicaInfo.lastSyncedLogicalTime,\n\t\t\t\t\toperations,\n\t\t\t\t\tbaselines,\n\t\t\t\t\tsince: provideChangesSince,\n\t\t\t\t};\n\t\t\t},\n\t\t);\n\t};\n\n\tcreatePresenceUpdate = async (data: {\n\t\tpresence?: any;\n\t\tinternal?: VerdantInternalPresence;\n\t}): Promise<PresenceUpdateMessage> => {\n\t\tconst localReplicaInfo = await this.meta.getLocalReplica();\n\t\treturn {\n\t\t\ttype: 'presence-update',\n\t\t\tpresence: data.presence,\n\t\t\treplicaId: localReplicaInfo.id,\n\t\t\tinternal: data.internal,\n\t\t};\n\t};\n\n\tcreateHeartbeat = async (): Promise<HeartbeatMessage> => {\n\t\treturn {\n\t\t\ttype: 'heartbeat',\n\t\t};\n\t};\n\n\tcreateAck = async (nonce: string): Promise<AckMessage> => {\n\t\tconst localReplicaInfo = await this.meta.getLocalReplica();\n\t\treturn {\n\t\t\ttype: 'ack',\n\t\t\ttimestamp: this.ctx.time.now,\n\t\t\treplicaId: localReplicaInfo.id,\n\t\t\tnonce,\n\t\t};\n\t};\n\n\tcreateDisconnecting = async (\n\t\treason: string,\n\t): Promise<DisconnectingMessage> => {\n\t\tconst localReplicaInfo = await this.meta.getLocalReplica();\n\t\treturn {\n\t\t\ttype: 'disconnecting',\n\t\t\treplicaId: localReplicaInfo.id,\n\t\t\treason,\n\t\t};\n\t};\n}\n", "import {\n\tapplyPatch,\n\tassignOid,\n\tisFileRef,\n\tObjectIdentifier,\n\tRef,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { AbstractTransaction, PersistenceMetadataDb } from './interfaces.js';\nimport type { PersistenceMetadata } from './PersistenceMetadata.js';\n\nexport class PersistenceRebaser {\n\tconstructor(\n\t\tprivate db: PersistenceMetadataDb,\n\t\tprivate meta: PersistenceMetadata,\n\t\tprivate ctx: Pick<\n\t\t\tContext,\n\t\t\t| 'closing'\n\t\t\t| 'log'\n\t\t\t| 'time'\n\t\t\t| 'internalEvents'\n\t\t\t| 'globalEvents'\n\t\t\t| 'config'\n\t\t\t| 'closeLock'\n\t\t\t| 'persistenceShutdownHandler'\n\t\t>,\n\t) {}\n\n\t/**\n\t * Autonomous rebases are only allowed for clients who have never synced. They\n\t * keep storage clean for non-syncing clients by compressing history.\n\t */\n\ttryAutonomousRebase = async () => {\n\t\tconst localReplicaInfo = await this.meta.getLocalReplica();\n\t\tif (localReplicaInfo.lastSyncedLogicalTime) return; // cannot autonomously rebase if we've synced\n\t\tif (this.ctx.closing || this.ctx.persistenceShutdownHandler.isShuttingDown)\n\t\t\treturn;\n\t\t// but if we have never synced... we can rebase everything!\n\t\tthis.ctx.log('debug', 'Running autonomous library rebase');\n\t\tawait this.runRebase(this.ctx.time.now);\n\t};\n\n\t/**\n\t * Attempt to autonomously rebase local documents without server intervention.\n\t * This can currently only happen for a client who has never synced before.\n\t * The goal is to allow local-only clients to compress their history to exactly\n\t * their undo stack.\n\t */\n\tprivate runRebase = async (globalAckTimestamp: string) => {\n\t\tif (this.ctx.closing || this.ctx.persistenceShutdownHandler.isShuttingDown)\n\t\t\treturn;\n\n\t\tawait this.db.transaction(\n\t\t\t{\n\t\t\t\tstoreNames: ['baselines', 'operations'],\n\t\t\t\tmode: 'readwrite',\n\t\t\t},\n\t\t\tasync (transaction) => {\n\t\t\t\t// find all operations before the global ack\n\t\t\t\tconst toRebase = new Set<ObjectIdentifier>();\n\t\t\t\tlet lastTimestamp;\n\t\t\t\tlet operationCount = 0;\n\t\t\t\tawait this.db.iterateAllOperations(\n\t\t\t\t\t(patch) => {\n\t\t\t\t\t\ttoRebase.add(patch.oid);\n\t\t\t\t\t\tlastTimestamp = patch.timestamp;\n\t\t\t\t\t\toperationCount++;\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tbefore: globalAckTimestamp,\n\t\t\t\t\t\ttransaction,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (!toRebase.size) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tthis.ctx.closing ||\n\t\t\t\t\tthis.ctx.persistenceShutdownHandler.isShuttingDown\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// rebase each affected document\n\t\t\t\tlet newBaselines = [];\n\t\t\t\tfor (const oid of toRebase) {\n\t\t\t\t\tnewBaselines.push(\n\t\t\t\t\t\tawait this.rebase(\n\t\t\t\t\t\t\toid,\n\t\t\t\t\t\t\tlastTimestamp || globalAckTimestamp,\n\t\t\t\t\t\t\ttransaction,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t\tthis.ctx.globalEvents.emit('rebase');\n\t};\n\n\t/**\n\t * Debounces rebase attempts to avoid thrashing the database with\n\t * rebase operations.\n\t */\n\tscheduleRebase = async (timestamp: string) => {\n\t\tif (this.rebaseTimeout) {\n\t\t\tclearTimeout(this.rebaseTimeout);\n\t\t}\n\t\tthis.rebaseTimeout = setTimeout(\n\t\t\tthis.runRebase,\n\t\t\tthis.ctx.config.persistence?.rebaseTimeout ?? 10000,\n\t\t\ttimestamp,\n\t\t);\n\t\tthis.ctx.log('debug', 'Scheduled rebase up to global ack', timestamp);\n\t};\n\tprivate rebaseTimeout: NodeJS.Timeout | null = null;\n\n\tprivate rebase = async (\n\t\toid: ObjectIdentifier,\n\t\tupTo: string,\n\t\ttransaction: AbstractTransaction,\n\t) => {\n\t\tif (this.ctx.closing || this.ctx.persistenceShutdownHandler.isShuttingDown)\n\t\t\treturn;\n\n\t\tconst baseline = await this.db.getBaseline(oid, { transaction });\n\t\tlet current: any = baseline?.snapshot || undefined;\n\t\tlet operationsApplied = 0;\n\t\tlet authz = baseline?.authz;\n\t\tconst deletedRefs: Ref[] = [];\n\n\t\tif (this.ctx.closing || this.ctx.persistenceShutdownHandler.isShuttingDown)\n\t\t\treturn;\n\n\t\tawait this.db.iterateEntityOperations(\n\t\t\toid,\n\t\t\t(patch) => {\n\t\t\t\t// FIXME: this seems like the wrong place to do this\n\t\t\t\t// but it's here as a safety measure...\n\t\t\t\tif (!baseline || patch.timestamp > baseline.timestamp) {\n\t\t\t\t\tcurrent = applyPatch(current, patch.data, deletedRefs);\n\t\t\t\t\tif (patch.data.op === 'initialize') {\n\t\t\t\t\t\tauthz = patch.authz;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// delete all prior operations to the baseline\n\t\t\t\toperationsApplied++;\n\t\t\t},\n\t\t\t{\n\t\t\t\tto: upTo,\n\t\t\t\ttransaction,\n\t\t\t},\n\t\t);\n\t\tif (current) {\n\t\t\tassignOid(current, oid);\n\t\t}\n\t\tconst newBaseline = {\n\t\t\toid,\n\t\t\tsnapshot: current,\n\t\t\ttimestamp: upTo,\n\t\t\tauthz,\n\t\t};\n\n\t\t// still time to cancel now...\n\t\tif (this.ctx.closing || this.ctx.persistenceShutdownHandler.isShuttingDown)\n\t\t\treturn;\n\n\t\t// FROM HERE, WE ARE COMMITTED TO THE REBASE -- otherwise data will be corrupted.\n\t\tthis.ctx.closeLock = (async () => {\n\t\t\tif (newBaseline.snapshot) {\n\t\t\t\tawait this.db.setBaselines([newBaseline], { transaction });\n\t\t\t} else {\n\t\t\t\tawait this.db.deleteBaseline(oid, { transaction });\n\t\t\t}\n\n\t\t\tawait this.db.deleteEntityOperations(oid, {\n\t\t\t\tto: upTo,\n\t\t\t\ttransaction,\n\t\t\t});\n\n\t\t\tthis.ctx.log(\n\t\t\t\t'debug',\n\t\t\t\t'rebased',\n\t\t\t\toid,\n\t\t\t\t'up to',\n\t\t\t\tupTo,\n\t\t\t\t':',\n\t\t\t\tcurrent,\n\t\t\t\t'and deleted',\n\t\t\t\toperationsApplied,\n\t\t\t\t'operations',\n\t\t\t);\n\n\t\t\t// cleanup deleted refs\n\t\t\tif (deletedRefs.length) {\n\t\t\t\tconst fileRefs = deletedRefs.filter(isFileRef);\n\t\t\t\tif (fileRefs.length) {\n\t\t\t\t\tthis.ctx.internalEvents.emit('filesDeleted', fileRefs);\n\t\t\t\t}\n\t\t\t}\n\t\t})();\n\n\t\treturn newBaseline;\n\t};\n}\n", "import { PersistenceDocumentDb } from './interfaces.js';\nimport { Context } from '../context/context.js';\nimport { decomposeOid, ObjectIdentifier } from '@verdant-web/common';\n\nexport class PersistenceDocuments {\n\tconstructor(\n\t\tprivate db: PersistenceDocumentDb,\n\t\tprivate ctx: Omit<Context, 'queries'>,\n\t) {}\n\n\treset = this.db.reset.bind(this.db);\n\n\tclose = this.db.close.bind(this.db);\n\n\tsaveEntities = async (\n\t\tentities: { oid: ObjectIdentifier; getSnapshot: () => any }[],\n\t\toptions?: { abort?: AbortSignal },\n\t) => {\n\t\tif (entities.length === 0) return;\n\n\t\t// filter entities to remove collections which don't\n\t\t// exist in the schema anymore\n\t\tconst currentCollectionSet = new Set(\n\t\t\tObject.keys(this.ctx.schema.collections),\n\t\t);\n\t\tconst collections: string[] = [];\n\t\tconst filteredEntities = entities.filter((entity) => {\n\t\t\tconst { collection } = decomposeOid(entity.oid);\n\t\t\tif (!currentCollectionSet.has(collection)) {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'warn',\n\t\t\t\t\t`Entity ${entity.oid} is in a collection that no longer exists in the schema. It will not be saved.`,\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!collections.includes(collection)) collections.push(collection);\n\t\t\treturn true;\n\t\t});\n\n\t\tif (collections.length === 0) return;\n\n\t\tthis.ctx.log('debug', 'Saving', filteredEntities.length, 'entities');\n\t\tawait this.db.saveEntities(filteredEntities, {\n\t\t\tabort: options?.abort,\n\t\t\tcollections,\n\t\t});\n\t\tthis.ctx.log('debug', 'Saved', filteredEntities.length, 'entities');\n\t\tthis.ctx.entityEvents.emit('collectionsChanged', collections);\n\t\tfor (const entity of entities) {\n\t\t\tthis.ctx.entityEvents.emit('documentChanged', entity.oid);\n\t\t}\n\t};\n\n\tfindOneOid = this.db.findOneOid.bind(this.db);\n\tfindAllOids = this.db.findAllOids.bind(this.db);\n\n\tstats = this.db.stats.bind(this.db);\n}\n", "import { getOidRoot, VerdantError } from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { ShutdownHandler } from '../context/ShutdownHandler.js';\nimport { getWipNamespace } from '../utils/wip.js';\nimport { ExportedData } from './interfaces.js';\nimport { migrate } from './migration/migrate.js';\nimport { PersistenceFiles } from './PersistenceFiles.js';\nimport { PersistenceMetadata } from './PersistenceMetadata.js';\nimport { PersistenceDocuments } from './PersistenceQueries.js';\n\nexport async function initializePersistence(ctx: Context) {\n\tconst initialSchema = ctx.schema;\n\tif (ctx.schema.wip) {\n\t\t// this is a WIP database, so we need to create a new namespace for the WIP data.\n\t\tctx.namespace = getWipNamespace(ctx.originalNamespace, ctx.schema);\n\t\tctx.log('info', '\uD83D\uDD28', 'Switched to WIP namespace', ctx.namespace);\n\t\t// check if this WIP database is already in use\n\t\tconst namespaces = await ctx.persistence.getNamespaces();\n\n\t\tif (!namespaces.includes(ctx.namespace)) {\n\t\t\t// copy all data to WIP namespace -- from the current version of local\n\t\t\t// data, not the WIP schema version. this may not be n-1, we might\n\t\t\t// be loading a WIP schema over older data.\n\t\t\tconst currentVersion = await ctx.persistence.getNamespaceVersion(\n\t\t\t\tctx.originalNamespace,\n\t\t\t);\n\n\t\t\tif (currentVersion === 0) {\n\t\t\t\t// there is no existing data. nothing to copy.\n\t\t\t\tctx.log('debug', 'No existing data to copy to WIP namespace');\n\t\t\t} else {\n\t\t\t\tconst currentSchema = ctx.oldSchemas?.find(\n\t\t\t\t\t(s) => s.version === currentVersion,\n\t\t\t\t);\n\t\t\t\tif (!currentSchema) {\n\t\t\t\t\tthrow new VerdantError(\n\t\t\t\t\t\tVerdantError.Code.MigrationPathNotFound,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t`Trying to open WIP database for version ${ctx.schema.version}, but the current local data is version ${currentVersion} and a historical schema for that version is not available.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tctx.log(\n\t\t\t\t\t'info',\n\t\t\t\t\t`Copying data from ${ctx.originalNamespace} to ${ctx.namespace}`,\n\t\t\t\t);\n\t\t\t\tawait ctx.persistence.copyNamespace(\n\t\t\t\t\tctx.originalNamespace,\n\t\t\t\t\tctx.namespace,\n\t\t\t\t\t// needs to be the original schema; the copy should be of the original\n\t\t\t\t\t// data and schema structure; the WIP schema migration application happens\n\t\t\t\t\t// below.\n\t\t\t\t\tctx.cloneWithOptions({\n\t\t\t\t\t\tschema: currentSchema,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst namespace = await ctx.persistence.openNamespace(ctx.namespace, ctx);\n\n\tctx.log('info', 'Opening persistence metadata', ctx.namespace);\n\tconst meta = new PersistenceMetadata(await namespace.openMetadata(ctx), ctx);\n\n\tctx.log('info', 'Opening persistence files', ctx.namespace);\n\tconst files = new PersistenceFiles(await namespace.openFiles(ctx), ctx);\n\n\tctx.log('info', 'Migrating document database');\n\tawait migrate({\n\t\tcontext: ctx,\n\t\tversion: ctx.schema.version,\n\t\tmeta,\n\t});\n\n\tctx.log('info', 'Opening persistence documents');\n\tif (ctx.schema.version <= 0) {\n\t\t// debugging....\n\t\tif (ctx.schema !== initialSchema) {\n\t\t\tctx.log(\n\t\t\t\t'critical',\n\t\t\t\t'Schema at initialization does not match original schema. This is likely a bug in Verdant!',\n\t\t\t);\n\t\t\tthrow new VerdantError(\n\t\t\t\tVerdantError.Code.ConfigurationError,\n\t\t\t\tundefined,\n\t\t\t\t`Schema at initialization does not match original schema. This is likely a bug in Verdant!`,\n\t\t\t);\n\t\t}\n\t\tthrow new VerdantError(\n\t\t\tVerdantError.Code.ConfigurationError,\n\t\t\tundefined,\n\t\t\t`Schema version must be greater than 0. Found version ${ctx.schema.version} with collections [${Object.keys(ctx.schema.collections).join(', ')}]\\n${JSON.stringify(ctx.schema)}`,\n\t\t);\n\t}\n\tconst documents = new PersistenceDocuments(\n\t\tawait namespace.openDocuments(ctx),\n\t\tctx,\n\t);\n\n\tif (!ctx.schema.wip) {\n\t\tconst namespaces = await ctx.persistence.getNamespaces();\n\t\t// cleanup old WIP databases\n\t\tfor (const namespace of namespaces) {\n\t\t\tif (namespace.startsWith(`@@wip_`)) {\n\t\t\t\tctx.log('debug', 'Cleaning up old WIP namespace', namespace);\n\t\t\t\tawait ctx.persistence.deleteNamespace(namespace, ctx);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { meta, files, documents };\n}\n\nexport async function importPersistence(\n\tctx: Context,\n\texportedData: ExportedData,\n): Promise<void> {\n\tctx.log('info', 'Importing data from export');\n\t// open persistence at the version of the import\n\tconst exportedSchema = ctx.oldSchemas?.find(\n\t\t(s) => s.version === exportedData.data.schemaVersion,\n\t);\n\tif (!exportedSchema) {\n\t\t// this means the user hasn't upgraded their CLI/client to include old schemas, or\n\t\t// this exported data comes from a version which has since been shortcut.\n\t\tthrow new Error(\n\t\t\t`Could not find schema for version ${exportedData.data.schemaVersion}`,\n\t\t);\n\t}\n\n\t// using a new namespace to put all of this into a temporary zone\n\tconst importedNamespace = `@@import_${Date.now()}`;\n\n\tconst importedContext = ctx.cloneWithOptions({\n\t\tschema: exportedSchema,\n\t\tnamespace: importedNamespace,\n\t\tdisableRebasing: true,\n\t\tpersistenceShutdownHandler: new ShutdownHandler(ctx.log),\n\t});\n\tawait importedContext.reinitialize();\n\tconst importedMeta = await importedContext.meta;\n\n\t// load imported data into persistence\n\tawait importedMeta.resetFrom(exportedData.data);\n\t// need to write indexes here!\n\tconst affectedOids = new Set<string>();\n\tfor (const baseline of exportedData.data.baselines) {\n\t\taffectedOids.add(getOidRoot(baseline.oid));\n\t}\n\tfor (const operation of exportedData.data.operations) {\n\t\taffectedOids.add(getOidRoot(operation.oid));\n\t}\n\tconst toSave = await Promise.all(\n\t\tArray.from(affectedOids).map(async (oid) => {\n\t\t\tconst snapshot = await importedMeta.getDocumentSnapshot(oid);\n\t\t\treturn {\n\t\t\t\toid,\n\t\t\t\tgetSnapshot: () => snapshot,\n\t\t\t};\n\t\t}),\n\t);\n\tawait (await importedContext.documents).saveEntities(toSave);\n\tawait (await importedContext.files).import(exportedData);\n\n\tctx.log('debug', 'Imported data into temporary namespace', importedNamespace);\n\n\t// shut down the imported databases\n\tawait importedContext.persistenceShutdownHandler.shutdown();\n\n\tif (exportedSchema.version !== ctx.schema.version) {\n\t\t// an upgrade of the imported data is needed ; it's an older version\n\t\t// of the schema.\n\n\t\t// upgrade the imported data to the latest schema by re-initializing\n\t\t// a context at the latest version, pointing at the imported namespace\n\t\tconst upgradedContext = importedContext.cloneWithOptions({\n\t\t\tpersistenceShutdownHandler: new ShutdownHandler(ctx.log),\n\t\t\tschema: ctx.schema,\n\t\t\toldSchemas: ctx.oldSchemas,\n\t\t});\n\t\tawait upgradedContext.reinitialize();\n\n\t\tctx.log('debug', 'Upgraded imported data to current schema');\n\n\t\tawait upgradedContext.persistenceShutdownHandler.shutdown();\n\n\t\tctx.log('debug', 'Shut down upgraded databases');\n\t}\n\n\t// shut down the persistence layer\n\tawait ctx.persistenceShutdownHandler.shutdown();\n\n\t// copy the imported data into the current namespace\n\tawait ctx.persistence.copyNamespace(importedNamespace, ctx.namespace, ctx);\n\tctx.log('debug', 'Copied imported data to primary namespace');\n\n\t// restart the persistence layer\n\tawait ctx.reinitialize();\n\tctx.log('debug', 'Reinitialized primary persistence layer');\n\n\t// verify integrity -- this can only be done if imported data was same\n\t// version as current schema, because migrations could add or remove\n\t// operations. still, it's a good sanity check.\n\tif (exportedData.data.schemaVersion === ctx.schema.version) {\n\t\tconst stats = await (await ctx.meta).stats();\n\t\tif (stats.operationsSize.count !== exportedData.data.operations.length) {\n\t\t\tctx.log(\n\t\t\t\t'critical',\n\t\t\t\t'Imported operations count mismatch',\n\t\t\t\t'expected',\n\t\t\t\texportedData.data.operations.length,\n\t\t\t\t'actual',\n\t\t\t\tstats.operationsSize.count,\n\t\t\t);\n\t\t\tthrow new VerdantError(\n\t\t\t\tVerdantError.Code.ImportFailed,\n\t\t\t\tundefined,\n\t\t\t\t'Imported operations count mismatch',\n\t\t\t);\n\t\t}\n\t\tif (stats.baselinesSize.count !== exportedData.data.baselines.length) {\n\t\t\tctx.log(\n\t\t\t\t'critical',\n\t\t\t\t'Imported documents count mismatch',\n\t\t\t\t'expected',\n\t\t\t\texportedData.data.baselines.length,\n\t\t\t\t'actual',\n\t\t\t\tstats.baselinesSize.count,\n\t\t\t);\n\t\t\tthrow new VerdantError(\n\t\t\t\tVerdantError.Code.ImportFailed,\n\t\t\t\tundefined,\n\t\t\t\t'Imported documents count mismatch',\n\t\t\t);\n\t\t}\n\t} else {\n\t\tctx.log(\n\t\t\t'debug',\n\t\t\t'Skipping integrity check due to schema version mismatch (not an error)',\n\t\t\t{\n\t\t\t\texportedVersion: exportedData.data.schemaVersion,\n\t\t\t\tcurrentVersion: ctx.schema.version,\n\t\t\t},\n\t\t);\n\t}\n\n\tctx.log('debug', 'Data copied to primary namespace');\n\n\t// cleanup the imported namespace\n\tawait ctx.persistence.deleteNamespace(importedNamespace, ctx);\n\n\tctx.log('debug', 'Deleted temporary namespace');\n\n\tctx.internalEvents.emit('persistenceReset');\n\tctx.log('info', 'Data imported successfully');\n\n\t// reset to allow future shutdowns.\n\tctx.persistenceShutdownHandler.reset();\n}\n", "import { TimestampProvider } from '@verdant-web/common';\n\nexport class Time {\n\tprivate overrideNow?: () => string;\n\tconstructor(\n\t\tprivate base: TimestampProvider,\n\t\tprivate version: number,\n\t) {}\n\n\tget now() {\n\t\treturn this.overrideNow ? this.overrideNow() : this.base.now(this.version);\n\t}\n\n\twithMigrationTime = async (version: number, run: () => void) => {\n\t\tthis.overrideNow = () => {\n\t\t\treturn this.base.zero(version);\n\t\t};\n\t\trun();\n\t\tthis.overrideNow = undefined;\n\t};\n\n\tupdate = this.base.update.bind(this.base);\n\n\tnowWithVersion = (version: number) => {\n\t\treturn this.base.now(version);\n\t};\n\n\tget zero() {\n\t\treturn this.base.zero(this.version);\n\t}\n\n\tzeroWithVersion = (version: number) => {\n\t\treturn this.base.zero(version);\n\t};\n}\n", "import {\n\tClientMessage,\n\tEventSubscriber,\n\tFileData,\n\tFileRef,\n\tHybridLogicalClockTimestampProvider,\n\tMigration,\n\tObjectIdentifier,\n\tOperation,\n\tPatchCreator,\n\tStorageSchema,\n\tVerdantError,\n} from '@verdant-web/common';\nimport { FakeWeakRef } from '../FakeWeakRef.js';\nimport { UndoHistory } from '../UndoHistory.js';\nimport type { Client } from '../client/Client.js';\nimport { debugLogger, noLogger, VerdantLogger } from '../logger.js';\nimport { PersistenceFiles } from '../persistence/PersistenceFiles.js';\nimport type { PersistenceMetadata } from '../persistence/PersistenceMetadata.js';\nimport type { PersistenceDocuments } from '../persistence/PersistenceQueries.js';\nimport { IdbPersistence } from '../persistence/idb/idbPersistence.js';\nimport {\n\tPersistedFileData,\n\tPersistenceImplementation,\n} from '../persistence/interfaces.js';\nimport { initializePersistence } from '../persistence/persistence.js';\nimport { ServerSyncOptions } from '../sync/Sync.js';\nimport { ShutdownHandler } from './ShutdownHandler.js';\nimport { Time } from './Time.js';\n\nexport interface ContextEnvironment {\n\tWebSocket: typeof WebSocket;\n\tfetch: typeof fetch;\n\tindexedDB: typeof indexedDB;\n\tlocation: Location;\n\thistory: History;\n}\n\nexport const defaultBrowserEnvironment: ContextEnvironment = {\n\tWebSocket: typeof WebSocket !== 'undefined' ? WebSocket : (undefined as any),\n\tfetch: typeof window !== 'undefined' ? window.fetch.bind(window) : fetch!,\n\tindexedDB: typeof indexedDB !== 'undefined' ? indexedDB : (undefined as any),\n\tlocation:\n\t\ttypeof window !== 'undefined' ? window.location : (undefined as any),\n\thistory: typeof window !== 'undefined' ? window.history : (undefined as any),\n};\n\nexport interface ContextInit {\n\t/** The schema used to create this client */\n\tschema: StorageSchema<any>;\n\toldSchemas: StorageSchema<any>[];\n\t/** Migrations, in order, to upgrade to each successive version of the schema */\n\tmigrations: Migration<any>[];\n\t/** Provide a sync config to turn on synchronization with a server */\n\tsync?: ServerSyncOptions;\n\t/**\n\t * Namespaces are used to separate data from different clients in IndexedDB.\n\t */\n\tnamespace: string;\n\t/**\n\t * Provide your own UndoHistory to have a unified undo system across multiple\n\t * clients if you so desire.\n\t */\n\tundoHistory?: UndoHistory;\n\t/**\n\t * Provide a log function to log internal debug messages\n\t */\n\tlog?: VerdantLogger | false;\n\tdisableRebasing?: boolean;\n\trebaseTimeout?: number;\n\t/**\n\t * Provide a specific schema number to override the schema version\n\t * in the database. This is useful for testing migrations or recovering\n\t * from a mistakenly deployed incorrect schema. A specific version is required\n\t * so that you don't leave this on accidentally for all new schemas.\n\t */\n\toverrideSchemaConflict?: number;\n\t/**\n\t * Configuration for file management\n\t */\n\tfiles?: FileConfig;\n\n\t/**\n\t * Override the default IndexedDB persistence implementation.\n\t */\n\tpersistence?: PersistenceImplementation;\n\n\t/**\n\t * Specify the environment dependencies needed for the client.\n\t * Normally these are provided by the browser, but in other\n\t * runtimes you may need to provide your own.\n\t */\n\tenvironment?: Partial<ContextEnvironment>;\n\n\t/**\n\t * Enables experimental WeakRef usage to cull documents\n\t * from cache that aren't being used. This is a performance\n\t * optimization which has been tested under all Verdant's test\n\t * suites but I still want to keep testing it in the real world\n\t * before turning it on.\n\t */\n\tEXPERIMENTAL_weakRefs?: boolean;\n\n\t/**\n\t * Customize querying behavior.\n\t */\n\tqueries?: QueryConfig;\n\n\tpersistenceShutdownHandler?: ShutdownHandler;\n}\n\n/**\n * Common components utilized across various client\n * services.\n */\nexport class Context {\n\tnamespace: string;\n\t/**\n\t * when in WIP mode, namespace might be set to a temporary value. This will always point to the\n\t * namespace the user passed in.\n\t */\n\toriginalNamespace: string;\n\ttime: Time;\n\n\t// async initialized services\n\tget meta(): Promise<PersistenceMetadata> {\n\t\treturn this.initializedPromise.then((init) => init.meta);\n\t}\n\tget documents(): Promise<PersistenceDocuments> {\n\t\treturn this.initializedPromise.then((init) => init.documents);\n\t}\n\tget files(): Promise<PersistenceFiles> {\n\t\treturn this.initializedPromise.then((init) => init.files);\n\t}\n\n\tundoHistory: UndoHistory;\n\tschema: StorageSchema;\n\toldSchemas: StorageSchema[];\n\tlog: VerdantLogger;\n\tentityEvents: EventSubscriber<{\n\t\tcollectionsChanged: (names: string[]) => void;\n\t\tdocumentChanged: (oid: ObjectIdentifier) => void;\n\t}>;\n\tinternalEvents: EventSubscriber<{\n\t\t/**\n\t\t * Fired when persisted data changes fundamentally, like resetting to 0,\n\t\t * or importing different data.\n\t\t */\n\t\tpersistenceReset: () => void;\n\t\tfilesDeleted: (files: FileRef[]) => void;\n\t\tfileAdded: (file: FileData) => void;\n\t\t[ev: `fileUploaded:${string}`]: (file: FileData) => void;\n\t\tfileUploaded: (file: FileData) => void;\n\t\toutgoingSyncMessage: (message: ClientMessage) => void;\n\t}>;\n\tglobalEvents: EventSubscriber<{\n\t\t/**\n\t\t * A change from a future version of the application has been\n\t\t * witnessed. These changes are not applied but it indicates\n\t\t * the app has been updated and we should prompt the user\n\t\t * to reload or have their app user manually reload.\n\t\t *\n\t\t * The parameter is the timestamp of the future change.\n\t\t */\n\t\tfutureSeen: (timestamp: string) => void;\n\t\t/**\n\t\t * The server requested this replica reset its state\n\t\t * completely. This can happen when the replica has\n\t\t * been offline for too long and reconnects.\n\t\t */\n\t\tresetToServer: () => void;\n\t\t/**\n\t\t * An operation has been processed by the system. This could be a locally sourced\n\t\t * operation or a remote operation from sync.\n\t\t */\n\t\toperation: (operation: Operation) => void;\n\t\t/**\n\t\t * Emitted when storage rebases history. This should never actually affect application behavior\n\t\t * or stored data, but is useful for debugging and testing.\n\t\t */\n\t\trebase: () => void;\n\t\tfileSaved: (file: FileData) => void;\n\t}>;\n\tweakRef = <T extends object>(value: T): WeakRef<T> => {\n\t\tif (this.init.EXPERIMENTAL_weakRefs) {\n\t\t\treturn new WeakRef(value);\n\t\t}\n\t\treturn new FakeWeakRef(value) as any;\n\t};\n\tmigrations: Migration<any>[];\n\t/** If this is present, any attempt to close the client should await it first. */\n\tcloseLock?: Promise<void>;\n\tpatchCreator: PatchCreator;\n\tpersistenceShutdownHandler: ShutdownHandler;\n\n\t// state\n\tclosing: boolean = false;\n\tpauseRebasing: boolean = false;\n\n\tconfig: {\n\t\tfiles?: FileConfig;\n\t\tsync?: SyncConfig;\n\t\tpersistence?: PersistenceConfig;\n\t\tqueries?: QueryConfig;\n\t};\n\n\tenvironment: ContextEnvironment;\n\n\tpersistence: PersistenceImplementation;\n\n\t/**\n\t * Must be defined by the Client once it exists. Attempts to use this before\n\t * it's ready will rightfully throw an error.\n\t */\n\tgetClient = (): Client => {\n\t\tthrow new VerdantError(\n\t\t\tVerdantError.Code.Unexpected,\n\t\t\tundefined,\n\t\t\t'Client not yet initialized. This is a Verdant bug, please report it.',\n\t\t);\n\t};\n\n\tconstructor(\n\t\tprivate init: ContextInit,\n\t\tinitPersistence?: ReturnType<typeof initializePersistence>,\n\t) {\n\t\t// if server-side and no alternative IndexedDB implementation was provided,\n\t\t// we can't initialize the storage\n\t\tif (typeof window === 'undefined' && !this.init.environment) {\n\t\t\tthrow new Error(\n\t\t\t\t'A Verdant client was initialized in an environment without a global Window or `environment` configuration. If you are using verdant in a server-rendered framework, you must enforce that all clients are initialized on the client-side, or you must provide some mock interface of the environment to the Client options.',\n\t\t\t);\n\t\t}\n\t\t// set static values\n\t\tthis.namespace = this.init.namespace;\n\t\tthis.originalNamespace = this.init.namespace;\n\t\tthis.time = new Time(\n\t\t\tnew HybridLogicalClockTimestampProvider(),\n\t\t\tthis.init.schema.version,\n\t\t);\n\t\tthis.log =\n\t\t\tthis.init.log === false ? noLogger : this.init.log || debugLogger('\uD83C\uDF3F');\n\t\tthis.migrations = init.migrations;\n\t\tthis.undoHistory = init.undoHistory || new UndoHistory();\n\t\tthis.entityEvents = new EventSubscriber();\n\t\tthis.internalEvents = new EventSubscriber();\n\t\tthis.globalEvents = new EventSubscriber();\n\t\tthis.schema = init.schema;\n\t\tthis.oldSchemas = init.oldSchemas;\n\t\tthis.patchCreator = new PatchCreator(() => this.time.now);\n\t\tthis.persistenceShutdownHandler =\n\t\t\tinit.persistenceShutdownHandler || new ShutdownHandler(this.log);\n\t\tthis.config = {\n\t\t\tfiles: init.files,\n\t\t\tsync: init.sync,\n\t\t\tpersistence: {\n\t\t\t\tdisableRebasing: init.disableRebasing,\n\t\t\t\trebaseTimeout: init.rebaseTimeout,\n\t\t\t},\n\t\t\tqueries: init.queries,\n\t\t};\n\t\tthis.environment = {\n\t\t\t...defaultBrowserEnvironment,\n\t\t\t...init.environment,\n\t\t};\n\t\tthis.persistence =\n\t\t\tinit.persistence || new IdbPersistence(this.environment.indexedDB);\n\t\tthis.initializedPromise = initPersistence || initializePersistence(this);\n\t\tthis.initializedPromise.then(() => {\n\t\t\tthis.log('info', 'Persistence initialized');\n\t\t});\n\t}\n\tprivate initializedPromise;\n\tget waitForInitialization(): Promise<void> {\n\t\treturn this.initializedPromise.then(() => {});\n\t}\n\treinitialize = async (): Promise<void> => {\n\t\tthis.initializedPromise = initializePersistence(this);\n\t\tawait this.initializedPromise;\n\t};\n\n\tcloneWithOptions(options: Partial<ContextInit>): Context {\n\t\tconst copy = new Context(\n\t\t\t{ ...this.init, ...options },\n\t\t\tthis.initializedPromise,\n\t\t);\n\t\treturn copy;\n\t}\n}\n\nexport interface FileConfig {\n\t/**\n\t * Override the heuristic for deciding when a deleted file can be cleaned up.\n\t * By default this waits 3 days since deletion, then deletes the file data.\n\t * If the file has been synchronized to a server, it could still be restored\n\t * if the server has not yet deleted it.\n\t */\n\tcanCleanupDeletedFile?: (file: PersistedFileData) => boolean;\n}\n\nexport interface ServerSyncEndpointProviderConfig {\n\t/**\n\t * The location of the endpoint used to retrieve an\n\t * authorization token for the client.\n\t */\n\tauthEndpoint?: string;\n\t/**\n\t * A custom function to retrieve authorization\n\t * data. Use whatever fetching mechanism you want.\n\t */\n\tfetchAuth?: () => Promise<{\n\t\taccessToken: string;\n\t}>;\n\t/**\n\t * A spec-compliant fetch implementation. If not provided,\n\t * the global fetch will be used. authEndpoint will\n\t * be used to fetch the token.\n\t */\n\tfetch?: typeof fetch;\n}\n\nexport type SyncTransportMode = 'realtime' | 'pull';\n\nexport interface SyncConfig<Profile = any, Presence = any>\n\textends ServerSyncEndpointProviderConfig {\n\t/**\n\t * When a client first connects, it will use this presence value.\n\t */\n\tinitialPresence: Presence;\n\t/**\n\t * Before connecting to the server, the local client will have\n\t * this value for their profile data. You can either cache and store\n\t * profile data from a previous connection or provide defaults like\n\t * empty strings.\n\t */\n\tdefaultProfile: Profile;\n\n\t/**\n\t * Provide `false` to disable transport selection. Transport selection\n\t * automatically switches between HTTP and WebSocket based sync depending\n\t * on the number of peers connected. If a user is alone, they will use\n\t * HTTP push/pull to sync changes. If another user joins, both users will\n\t * be upgraded to websockets.\n\t *\n\t * Provide `peers-only` to only automatically use websockets if other\n\t * users connect, but not if another device for the current user connects.\n\t * By default, automatic transport selection will upgrade to websockets if\n\t * another device from the current user connects, but if realtime sync is\n\t * not necessary for such cases, you can save bandwidth by disabling this.\n\t *\n\t * Turning off this feature allows you more control over the transport\n\t * which can be useful for low-power devices or to save server traffic.\n\t * To modify transport modes manually, utilize `client.sync.setMode`.\n\t * The built-in behavior is essentially switching modes based on\n\t * the number of peers detected by client.sync.presence.\n\t */\n\tautomaticTransportSelection?: boolean | 'peers-only';\n\tinitialTransport?: SyncTransportMode;\n\tautoStart?: boolean;\n\t/**\n\t * Optionally specify an interval, in milliseconds, to poll the server\n\t * when in pull mode.\n\t */\n\tpullInterval?: number;\n\t/**\n\t * Presence updates are batched to reduce number of requests / messages\n\t * sent to the server. You can specify the batching time slice, in milliseconds,\n\t */\n\tpresenceUpdateBatchTimeout?: number;\n\t/**\n\t * Experimental: sync messages over a broadcast channel between tabs.\n\t * Fixes tabs not reactively updating to changes when other tabs are open,\n\t * but is not yet thoroughly vetted.\n\t */\n\tuseBroadcastChannel?: boolean;\n\t/**\n\t * Listen for outgoing messages from the client to the server.\n\t * Not sure why you want to do this, but be careful.\n\t */\n\tonOutgoingMessage?: (message: ClientMessage) => void;\n\n\tEXPERIMENTAL_backgroundSync?: boolean;\n}\n\nexport interface PersistenceConfig {\n\tdisableRebasing?: boolean;\n\trebaseTimeout?: number;\n}\n\nexport interface QueryConfig {\n\t/**\n\t * Milliseconds to hold a query in memory after it is unsubscribed before\n\t * disposing of it. Once a query is disposed, it must be loaded fresh again\n\t * on next use. Queries are cached based on their `key`, which you can\n\t * manually override. By default keys are determined by the parameters\n\t * passed to the query.\n\t *\n\t * Defaults to 5 seconds.\n\t */\n\tevictionTime?: number;\n}\n\nexport type ContextWithoutPersistence = Omit<\n\tContext,\n\t'meta' | 'documents' | 'files'\n>;\n", "import {\n\taddFieldDefaults,\n\tassert,\n\tAuthorizationKey,\n\tconstrainEntity,\n\tcreateOid,\n\tisRootOid,\n\tSchemaCollection,\n\tStorageCollectionSchema,\n\tStorageDocument,\n\tStorageSchema,\n} from '@verdant-web/common';\nimport { EntityCreateOptions, EntityStore } from '../entities/EntityStore.js';\nimport { ObjectEntity } from '../index.js';\n\n/**\n * Exposes functionality for creating documents,\n * the only mutation which is available as an entry\n * point in the storage system.\n */\nexport class DocumentManager<Schema extends StorageSchema<any>> {\n\tconstructor(\n\t\tprivate schema: Schema,\n\t\tprivate entities: EntityStore,\n\t) {}\n\n\tprivate getOid = (collection: string, init: any) => {\n\t\tconst primaryKeyName = this.schema.collections[collection]\n\t\t\t.primaryKey as Exclude<\n\t\t\tkeyof StorageDocument<SchemaCollection<Schema, any>>,\n\t\t\tsymbol\n\t\t>;\n\t\tconst primaryKey = init[primaryKeyName];\n\t\tassert(\n\t\t\tprimaryKey,\n\t\t\t`Document must have a primary key: ${primaryKeyName.toString()} (got: ${JSON.stringify(\n\t\t\t\tinit,\n\t\t\t)})`,\n\t\t);\n\t\treturn createOid(collection, primaryKey);\n\t};\n\n\tprivate addDefaults = (collectionName: string, init: any) => {\n\t\tconst collection = this.schema.collections[\n\t\t\tcollectionName\n\t\t] as StorageCollectionSchema;\n\t\treturn addFieldDefaults(collection, init);\n\t};\n\n\tprivate validate = (collectionName: string, init: any) => {\n\t\tconst collection = this.schema.collections[\n\t\t\tcollectionName\n\t\t] as StorageCollectionSchema;\n\t\treturn constrainEntity(collection.fields, init);\n\t};\n\n\tcreate = async (\n\t\tcollection: string,\n\t\tinit: any,\n\t\toptions: {\n\t\t\tundoable?: boolean;\n\t\t\taccess?: AuthorizationKey;\n\t\t\tsilenceAccessControlWithPrimaryKeyWarning?: boolean;\n\t\t} = {},\n\t) => {\n\t\tconst widenedOptions = options as EntityCreateOptions;\n\t\tconst defaulted = this.addDefaults(collection, init);\n\t\tconst validated = this.validate(collection, defaulted);\n\t\tconst oid = this.getOid(collection, validated);\n\n\t\tif (options.access) {\n\t\t\tconst collectionSchema = this.schema.collections[collection];\n\t\t\tif (\n\t\t\t\toptions.access !== 'shared' &&\n\t\t\t\tinit[collectionSchema.primaryKey] &&\n\t\t\t\t!options.silenceAccessControlWithPrimaryKeyWarning\n\t\t\t) {\n\t\t\t\t// using a custom primary key with access control is not supported.\n\t\t\t\t// resulting docs could collide with existing docs with different permissions,\n\t\t\t\t// leading to confusing results. this logs a warning.\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`Using a custom primary key with access control is not supported. This may result in corrupted documents. Read more about why: https://verdant.dev/docs/sync/access#a-warning-about-custom-primaryKey`,\n\t\t\t\t);\n\t\t\t}\n\t\t\twidenedOptions.access = options.access;\n\t\t}\n\n\t\t// documents are always objects at the root\n\t\treturn this.entities.create(validated, oid, widenedOptions) as any;\n\t};\n\n\tdelete = async (\n\t\tcollection: string,\n\t\tprimaryKey: string,\n\t\toptions: { undoable?: boolean } = {},\n\t) => {\n\t\tconst oid = createOid(collection, primaryKey);\n\t\treturn this.entities.delete(oid, options);\n\t};\n\n\tdeleteAll = async (\n\t\tids: [string, string][],\n\t\toptions: { undoable?: boolean } = {},\n\t) => {\n\t\treturn this.entities.deleteAll(\n\t\t\tids.map(([collection, primaryKey]) => createOid(collection, primaryKey)),\n\t\t\toptions,\n\t\t);\n\t};\n\n\tdeleteAllFromCollection = async (\n\t\tcollection: string,\n\t\tids: string[],\n\t\toptions: { undoable?: boolean } = {},\n\t) => {\n\t\treturn this.entities.deleteAll(\n\t\t\tids.map((primaryKey) => createOid(collection, primaryKey)),\n\t\t\toptions,\n\t\t);\n\t};\n\n\t/**\n\t * Creates a clone of the given document entity, returning a new\n\t * document entity in the given collection. The primary key of\n\t * the original document will be regenerated automatically and\n\t * access will be copied from the original. Both can be overridden\n\t * explicitly via options.\n\t */\n\tclone = async <TInit>(\n\t\tcollection: string,\n\t\tentity: ObjectEntity<TInit, any>,\n\t\toptions: {\n\t\t\tundoable?: boolean;\n\t\t\taccess?: AuthorizationKey;\n\t\t\tprimaryKey?: string;\n\t\t\t/**\n\t\t\t * Modify the data before cloning\n\t\t\t */\n\t\t\tupdate?: (init: TInit) => TInit;\n\t\t} = {},\n\t) => {\n\t\tif (!isRootOid(entity.uid)) {\n\t\t\tthrow new Error('Cannot clone non-root documents');\n\t\t}\n\t\t// take the entity snapshot\n\t\tconst snapshot = entity.getSnapshot() as any;\n\t\t// remove the primary key\n\t\tconst collectionSchema = this.schema.collections[collection];\n\t\tdelete snapshot[collectionSchema.primaryKey];\n\t\t// if collection schema's primary key doesn't have a default value,\n\t\t// a user-supplied value is required\n\t\tif (!collectionSchema.fields[collectionSchema.primaryKey].default) {\n\t\t\tif (!options.primaryKey) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Error cloning document from collection ${collection}: collection does not have a default on primary key. You must supply a value to options.primaryKey for the clone.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tsnapshot[collectionSchema.primaryKey] = options.primaryKey;\n\t\t}\n\t\t// copy authorization of original unless user supplied override\n\t\tif (entity.access && !options.access) {\n\t\t\toptions.access = entity.access;\n\t\t}\n\t\tconst final = options.update ? options.update(snapshot) : snapshot;\n\t\treturn this.create(collection, final, options);\n\t};\n}\n", "import {\n\tAuthorizationKey,\n\tDocumentBaseline,\n\tFileData,\n\tObjectIdentifier,\n\tOperation,\n\tStorageObjectFieldSchema,\n\tVerdantError,\n\tassert,\n\tassignOid,\n\tdecomposeOid,\n\tgetOidRoot,\n\tgroupBaselinesByRootOid,\n\tgroupPatchesByOid,\n\tgroupPatchesByRootOid,\n\tisRootOid,\n\tremoveOidsFromAllSubObjects,\n} from '@verdant-web/common';\nimport { WeakEvent } from 'weak-event';\nimport { Context } from '../context/context.js';\nimport { FileManager } from '../files/FileManager.js';\nimport { processValueFiles } from '../files/utils.js';\nimport { Disposable } from '../utils/Disposable.js';\nimport { Entity } from './Entity.js';\nimport { EntityFamilyMetadata } from './EntityMetadata.js';\nimport { OperationBatcher } from './OperationBatcher.js';\n\nenum AbortReason {\n\tReset,\n}\n\nexport type EntityStoreEventData = {\n\toid: ObjectIdentifier;\n\toperations?: Record<string, Operation[]>;\n\tbaselines?: DocumentBaseline[];\n\tisLocal: boolean;\n};\n\nexport type EntityStoreEvents = {\n\tadd: WeakEvent<EntityStore, EntityStoreEventData>;\n\treplace: WeakEvent<EntityStore, EntityStoreEventData>;\n\tresetAll: WeakEvent<EntityStore, void>;\n};\n\nexport interface IncomingData {\n\toperations?: Operation[];\n\tbaselines?: DocumentBaseline[];\n\treset?: boolean;\n\tisLocal?: boolean;\n}\n\nexport interface EntityCreateOptions {\n\tundoable?: boolean;\n\taccess?: AuthorizationKey;\n}\n\nexport class EntityStore extends Disposable {\n\tprivate ctx;\n\tprivate files;\n\tprivate batcher;\n\tprivate events: EntityStoreEvents = {\n\t\tadd: new WeakEvent(),\n\t\treplace: new WeakEvent(),\n\t\tresetAll: new WeakEvent(),\n\t};\n\tprivate cache = new Map<ObjectIdentifier, WeakRef<Entity>>();\n\tprivate pendingEntityPromises = new Map<\n\t\tObjectIdentifier,\n\t\tPromise<Entity | null>\n\t>();\n\t// halts the current data queue processing\n\tprivate abortDataQueueController = new AbortController();\n\tprivate ongoingResetPromise: Promise<void> | null = null;\n\tprivate entityFinalizationRegistry = new FinalizationRegistry(\n\t\t(oid: ObjectIdentifier) => {\n\t\t\tthis.ctx.log('debug', 'Entity GC', oid);\n\t\t},\n\t);\n\n\tconstructor({ ctx, files }: { ctx: Context; files: FileManager }) {\n\t\tsuper();\n\n\t\tthis.ctx = ctx;\n\t\tthis.files = files;\n\t\tthis.batcher = new OperationBatcher({\n\t\t\tctx,\n\t\t\tentities: this,\n\t\t});\n\t\tthis.addDispose(\n\t\t\tthis.ctx.internalEvents.subscribe('persistenceReset', this.clearCache),\n\t\t);\n\t}\n\n\t// expose batch APIs\n\tget batch() {\n\t\treturn this.batcher.batch;\n\t}\n\tget flushAllBatches() {\n\t\treturn this.batcher.flushAll;\n\t}\n\n\t// internal-ish API to load remote / stored data\n\taddData = async (data: IncomingData) => {\n\t\tif (this.disposed) {\n\t\t\tthis.ctx.log('warn', 'EntityStore is disposed, not adding incoming data');\n\t\t\treturn;\n\t\t}\n\t\t// for resets - abort any other changes, reset everything,\n\t\t// then proceed\n\t\tif (data.reset) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'info',\n\t\t\t\t'Resetting local store to replicate remote synced data - dropping any current transactions',\n\t\t\t);\n\t\t\t// cancel any other ongoing data - it will all\n\t\t\t// be replaced by the reset\n\t\t\tthis.abortDataQueueController.abort(AbortReason.Reset);\n\t\t\tthis.abortDataQueueController = new AbortController();\n\t\t\tthis.ongoingResetPromise = this.resetData().finally(() => {\n\t\t\t\tthis.ongoingResetPromise = null;\n\t\t\t\tthis.ctx.globalEvents.emit('resetToServer');\n\t\t\t});\n\t\t}\n\n\t\t// await either the reset we just started, or any that was\n\t\t// in progress when this data came in.\n\t\tif (this.ongoingResetPromise) {\n\t\t\tthis.ctx.log('debug', 'Waiting for ongoing reset to complete');\n\t\t\tawait this.ongoingResetPromise;\n\t\t\tthis.ctx.log('debug', 'Ongoing reset complete');\n\t\t}\n\n\t\tawait this.processData(data);\n\t};\n\n\tempty = async () => {\n\t\tawait (await this.ctx.documents).reset();\n\t\tthis.events.resetAll.invoke(this);\n\t\tthis.cache.clear();\n\t};\n\n\tprivate resetData = async () => {\n\t\tif (this.disposed) {\n\t\t\tthis.ctx.log('warn', 'EntityStore is disposed, not resetting local data');\n\t\t\treturn;\n\t\t}\n\t\tawait (await this.ctx.meta).reset();\n\t\tawait (await this.ctx.documents).reset();\n\t\tthis.events.resetAll.invoke(this);\n\t};\n\n\tprivate processData = async (data: IncomingData) => {\n\t\tif (this.disposed) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'warn',\n\t\t\t\t'EntityStore is disposed, not processing incoming data',\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst baselines = data?.baselines ?? [];\n\t\tconst operations = data?.operations ?? [];\n\n\t\tif (baselines.length === 0 && operations.length === 0) {\n\t\t\tthis.ctx.log('debug', 'No data to process');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.ctx.log('debug', 'Processing incoming data', {\n\t\t\toperations: operations.length,\n\t\t\tbaselines: baselines.length,\n\t\t\treset: !!data.reset,\n\t\t});\n\n\t\tconst allDocumentOids: ObjectIdentifier[] = Array.from(\n\t\t\tnew Set(\n\t\t\t\tbaselines\n\t\t\t\t\t.map((b) => getOidRoot(b.oid))\n\t\t\t\t\t.concat(operations.map((o) => getOidRoot(o.oid))),\n\t\t\t),\n\t\t);\n\t\tconst baselinesGroupedByOid = groupBaselinesByRootOid(baselines);\n\t\tconst operationsGroupedByOid = groupPatchesByRootOid(operations);\n\n\t\tthis.ctx.log('debug', 'Applying data to live entities');\n\t\t// synchronously add/replace data in any open entities via eventing\n\t\tfor (const oid of allDocumentOids) {\n\t\t\tconst baselines = baselinesGroupedByOid[oid];\n\t\t\tconst operations = operationsGroupedByOid[oid] ?? [];\n\t\t\tconst groupedOperations = groupPatchesByOid(operations);\n\t\t\t// what happens if an entity is being hydrated\n\t\t\t// while this is happening? - we wait for the hydration promise\n\t\t\t// to complete, then invoke the event\n\t\t\tconst event = data.reset ? this.events.replace : this.events.add;\n\t\t\tconst hydrationPromise = this.pendingEntityPromises.get(oid);\n\t\t\tif (hydrationPromise) {\n\t\t\t\tthis.ctx.log('debug', 'Waiting for ongoing entity hydration', oid);\n\t\t\t\thydrationPromise.then(() => {\n\t\t\t\t\tevent.invoke(this, {\n\t\t\t\t\t\toid,\n\t\t\t\t\t\tbaselines,\n\t\t\t\t\t\toperations: groupedOperations,\n\t\t\t\t\t\tisLocal: false,\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.ctx.log('debug', 'Applying data to entity', oid);\n\t\t\t\tevent.invoke(this, {\n\t\t\t\t\toid,\n\t\t\t\t\tbaselines,\n\t\t\t\t\toperations: groupedOperations,\n\t\t\t\t\tisLocal: false,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tconst abortOptions = {\n\t\t\tabort: this.abortDataQueueController.signal,\n\t\t};\n\n\t\t// then, asynchronously add to the database\n\t\t// this also emits messages to sync\n\t\t// TODO: could messages be sent to sync before storage,\n\t\t// so that realtime is lower latency? What would happen\n\t\t// if the storage failed?\n\t\tawait (await this.ctx.meta).insertData(data, abortOptions);\n\t\tthis.ctx.log(\n\t\t\t'debug',\n\t\t\t'Data processing complete, all data saved to metadata db.',\n\t\t);\n\n\t\t// recompute all affected documents for querying\n\t\tconst entities = await Promise.all(\n\t\t\tallDocumentOids.map(async (oid) => {\n\t\t\t\tconst entity = await this.hydrate(oid, abortOptions);\n\t\t\t\t// if the entity is not found, we return a stub that\n\t\t\t\t// indicates it's deleted and should be cleared\n\t\t\t\treturn (\n\t\t\t\t\tentity ?? {\n\t\t\t\t\t\toid,\n\t\t\t\t\t\tgetSnapshot(): any {\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\t\ttry {\n\t\t\tthis.ctx.log('debug', 'Saving entities to queryable storage');\n\t\t\tawait (await this.ctx.documents).saveEntities(entities, abortOptions);\n\t\t} catch (err) {\n\t\t\tif (this.disposed) {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'warn',\n\t\t\t\t\t'Error saving entities to queryable storage - EntityStore is disposed',\n\t\t\t\t\terr,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'error',\n\t\t\t\t\t'Error saving entities to queryable storage',\n\t\t\t\t\terr,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t};\n\n\t// internal-ish API for creating Entities from OIDs\n\t// when query results come in\n\thydrate = async (\n\t\toid: string,\n\t\topts?: { abort: AbortSignal },\n\t): Promise<Entity | null> => {\n\t\tif (!isRootOid(oid)) {\n\t\t\tthrow new Error('Cannot hydrate non-root entity');\n\t\t}\n\n\t\tif (this.cache.has(oid)) {\n\t\t\tconst cached = this.cache.get(oid);\n\t\t\tif (cached) {\n\t\t\t\tconst entity = cached.deref();\n\t\t\t\tif (entity) {\n\t\t\t\t\tif (entity.deleted) {\n\t\t\t\t\t\tthis.ctx.log('debug', 'Cached entity is deleted', oid);\n\t\t\t\t\t\t// debugger;\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tthis.ctx.log('debug', 'Using cached hydrated entity', oid);\n\t\t\t\t\treturn entity;\n\t\t\t\t} else {\n\t\t\t\t\tthis.ctx.log('debug', \"Removing GC'd entity from cache\", oid);\n\t\t\t\t\tthis.cache.delete(oid);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// we don't want to hydrate two entities in parallel, so\n\t\t// we use a promise to ensure that only one is ever\n\t\t// constructed at a time\n\t\tconst pendingPromise = this.pendingEntityPromises.get(oid);\n\t\tif (!pendingPromise) {\n\t\t\tthis.ctx.log('debug', 'Hydrating entity from storage', oid);\n\t\t\tconst entity = this.constructEntity(oid);\n\t\t\tif (!entity) {\n\t\t\t\tthis.ctx.log('warn', 'Entity schema not found, cannot construct', oid);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst pendingPromise = this.loadEntity(entity, opts);\n\t\t\tpendingPromise.finally(() => {\n\t\t\t\tthis.pendingEntityPromises.delete(oid);\n\t\t\t\tthis.ctx.log('debug', 'Hydration complete', oid);\n\t\t\t});\n\t\t\tthis.pendingEntityPromises.set(oid, pendingPromise);\n\t\t\treturn pendingPromise;\n\t\t} else {\n\t\t\tthis.ctx.log('debug', 'Waiting for ongoing entity hydration', oid);\n\t\t\treturn pendingPromise;\n\t\t}\n\t};\n\n\tdestroy = async () => {\n\t\tthis.ctx.log('warn', 'Disposing EntityStore');\n\t\tthis.dispose();\n\t\tawait this.batcher.flushAll();\n\t};\n\n\t// public APIs for manipulating entities\n\n\t/**\n\t * Creates a new Entity with the given initial data.\n\t */\n\tcreate = async (\n\t\tinitial: any,\n\t\toid: ObjectIdentifier,\n\t\t{ undoable = true, access }: EntityCreateOptions = {},\n\t) => {\n\t\tthis.ctx.log('debug', 'Creating new entity', oid);\n\t\tconst { collection } = decomposeOid(oid);\n\t\t// remove any OID associations from the initial data\n\t\tremoveOidsFromAllSubObjects(initial);\n\t\t// grab files and replace them with refs\n\t\tconst fileRefs: FileData[] = [];\n\t\tconst processed = processValueFiles(initial, fileRefs.push.bind(fileRefs));\n\n\t\tassignOid(processed, oid);\n\n\t\t// validate that schema exists\n\t\tconst { schema } = this.getCollectionSchema(collection);\n\t\tif (!schema) {\n\t\t\tthrow new Error(`Collection schema not found for ${collection}`);\n\t\t}\n\n\t\tconst operations = this.ctx.patchCreator.createInitialize(\n\t\t\tprocessed,\n\t\t\toid,\n\t\t\taccess,\n\t\t);\n\t\tawait this.batcher.commitOperations(operations, {\n\t\t\tundoable: !!undoable,\n\t\t});\n\n\t\t// TODONE: what happens if you create an entity with an OID that already\n\t\t// exists?\n\t\t// A: it will overwrite the existing entity\n\n\t\t// wait for the entity to load and cache before returning\n\t\tconst entity = await this.hydrate(oid);\n\t\tif (!entity) {\n\t\t\t// something failed when creating the entity\n\t\t\tthis.ctx.log(\n\t\t\t\t'error',\n\t\t\t\t'Failed to create entity; hydrated entity is null. Hopefully an error is logged above.',\n\t\t\t\toid,\n\t\t\t);\n\t\t\tthrow new VerdantError(\n\t\t\t\tVerdantError.Code.Unexpected,\n\t\t\t\tundefined,\n\t\t\t\t`Failed to create document ${oid}`,\n\t\t\t);\n\t\t}\n\t\t// add files with entity as parent\n\t\t// note: these .add invocations have async behavior -- it should upload any files to the\n\t\t// server if sync is active. but we don't need to wait for it to make the entity usable as file\n\t\t// data should already be locally available.\n\t\tthis.ctx.log(\n\t\t\t'debug',\n\t\t\t'Associating',\n\t\t\tfileRefs.length,\n\t\t\t'files to new entity',\n\t\t\toid,\n\t\t);\n\t\tfileRefs.forEach((file) => this.files.add(file, entity));\n\t\treturn entity;\n\t};\n\n\tdeleteAll = async (\n\t\toids: ObjectIdentifier[],\n\t\toptions?: { undoable?: boolean },\n\t) => {\n\t\tthis.ctx.log('info', 'Deleting documents', oids);\n\t\tassert(\n\t\t\toids.every((oid) => oid === getOidRoot(oid)),\n\t\t\t'Only root documents may be deleted via client methods',\n\t\t);\n\n\t\tconst entities = await Promise.all(oids.map((oid) => this.hydrate(oid)));\n\n\t\tconst operations: Operation[] = [];\n\t\tfor (const entity of entities) {\n\t\t\tif (entity) {\n\t\t\t\tconst oids = entity.__getFamilyOids__();\n\t\t\t\tconst deletes = this.ctx.patchCreator.createDeleteAll(oids);\n\t\t\t\tfor (const op of deletes) {\n\t\t\t\t\top.authz = entity.access;\n\t\t\t\t}\n\t\t\t\toperations.push(...deletes);\n\t\t\t}\n\t\t}\n\n\t\tawait this.batcher.commitOperations(operations, {\n\t\t\tundoable: options?.undoable === undefined ? true : options.undoable,\n\t\t});\n\n\t\t// remove the entities from cache\n\t\toids.forEach((oid) => {\n\t\t\tthis.cache.delete(oid);\n\t\t\tthis.ctx.log('debug', 'Deleted document from cache', oid);\n\t\t});\n\t};\n\n\tdelete = async (oid: ObjectIdentifier, options?: { undoable?: boolean }) => {\n\t\treturn this.deleteAll([oid], options);\n\t};\n\n\tprivate getCollectionSchema = (\n\t\tcollectionName: string,\n\t): {\n\t\tschema: StorageObjectFieldSchema<any> | null;\n\t\treadonlyKeys: string[];\n\t} => {\n\t\tconst schema = this.ctx.schema.collections[collectionName];\n\t\tif (!schema) {\n\t\t\tthis.ctx.log('warn', `Missing schema for collection: ${collectionName}`);\n\t\t\treturn {\n\t\t\t\tschema: null,\n\t\t\t\treadonlyKeys: [],\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\t// convert to object schema for compatibility\n\t\t\tschema: {\n\t\t\t\ttype: 'object',\n\t\t\t\tnullable: false,\n\t\t\t\tproperties: schema.fields as any,\n\t\t\t},\n\t\t\treadonlyKeys: [schema.primaryKey],\n\t\t};\n\t};\n\n\t/**\n\t * Constructs an entity from an OID, but does not load it or add it to the cache.\n\t */\n\tprivate constructEntity = (oid: string): Entity | null => {\n\t\tassert(!!oid, 'Cannot construct entity without OID');\n\t\tconst { collection } = decomposeOid(oid);\n\t\tconst { schema, readonlyKeys } = this.getCollectionSchema(collection);\n\n\t\tif (!schema) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (this.disposed) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'warn',\n\t\t\t\t'Cannot hydrate entity after store has been disposed',\n\t\t\t);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst metadataFamily = new EntityFamilyMetadata({\n\t\t\tctx: this.ctx,\n\t\t\tonPendingOperations: this.onPendingOperations,\n\t\t\trootOid: oid,\n\t\t});\n\n\t\t// this is created synchronously so it's immediately available\n\t\t// to begin capturing incoming data.\n\t\treturn new Entity({\n\t\t\tctx: this.ctx,\n\t\t\toid,\n\t\t\tschema,\n\t\t\treadonlyKeys,\n\t\t\tfiles: this.files,\n\t\t\tmetadataFamily: metadataFamily,\n\t\t\tstoreEvents: this.events,\n\t\t\tdeleteSelf: this.delete.bind(this, oid),\n\t\t});\n\t};\n\n\tprivate onPendingOperations = (operations: Operation[]) => {\n\t\tthis.batcher.addOperations(operations);\n\t};\n\n\tdiscardPendingOperation = (operation: Operation) => {\n\t\tconst root = getOidRoot(operation.oid);\n\t\tthis.cache.get(root)?.deref()?.__discardPendingOperation__(operation);\n\t};\n\n\t/**\n\t * Loads initial Entity data from storage\n\t */\n\tprivate loadEntity = async (\n\t\tentity: Entity,\n\t\topts?: { abort: AbortSignal },\n\t): Promise<Entity | null> => {\n\t\tawait this.loadEntityData(entity, opts);\n\n\t\t// only set the cache after loading.\n\t\t// TODO: is this cache/promise stuff redundant?\n\t\tthis.cache.set(entity.oid, this.ctx.weakRef(entity));\n\t\tthis.entityFinalizationRegistry.register(entity, entity.oid);\n\n\t\treturn entity;\n\t};\n\n\tprivate loadEntityData = async (\n\t\tentity: Entity,\n\t\topts?: { abort: AbortSignal },\n\t) => {\n\t\tconst { operations, baselines } = await (\n\t\t\tawait this.ctx.meta\n\t\t).getDocumentData(entity.oid, opts);\n\n\t\tif (!baselines.length && !Object.keys(operations).length) {\n\t\t\tthis.ctx.log('debug', 'No data found for entity', entity.oid);\n\t\t\treturn null;\n\t\t}\n\n\t\tthis.ctx.log('debug', 'Loaded entity from storage', entity.oid);\n\n\t\tthis.events.replace.invoke(this, {\n\t\t\toid: entity.oid,\n\t\t\tbaselines,\n\t\t\toperations,\n\t\t\tisLocal: false,\n\t\t});\n\n\t\treturn entity;\n\t};\n\n\t/**\n\t * Drops all entities from the cache. Any entities\n\t * referenced will go 'dead'...\n\t */\n\tclearCache = () => {\n\t\tthis.ctx.log('debug', 'Emptying entity cache');\n\t\tthis.cache.clear();\n\t};\n}\n", "import {\n\tcreateFileRef,\n\tFileData,\n\tisFile,\n\tisFileData,\n} from '@verdant-web/common';\nimport cuid from 'cuid';\n\nexport function createFileData(file: File): FileData {\n\treturn {\n\t\tid: cuid(),\n\t\tfile: file,\n\t\turl: undefined,\n\t\tremote: false,\n\t\tname: file.name,\n\t\ttype: file.type,\n\t};\n}\n\n/**\n * MUTATES the value.\n * Replaces File values with refs and returns the normalized value.\n * The list of files passed to the second argument will be populated with the files found in the value.\n */\nexport function processValueFiles(\n\tvalue: any,\n\tonFileIdentified: (fileData: FileData) => void,\n): any {\n\tif (typeof window !== 'undefined' && isFile(value)) {\n\t\tconst data = createFileData(value);\n\t\tonFileIdentified(data);\n\t\treturn createFileRef(data.id);\n\t}\n\n\tif (isFileData(value)) {\n\t\t// create a new ID for the file\n\t\tconst cloned = { ...value, id: cuid() };\n\t\tonFileIdentified(cloned);\n\t\treturn createFileRef(cloned.id);\n\t}\n\n\tif (Array.isArray(value)) {\n\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\tvalue[i] = processValueFiles(value[i], onFileIdentified);\n\t\t}\n\t\treturn value;\n\t}\n\n\tif (typeof value === 'object') {\n\t\tfor (const key in value) {\n\t\t\tvalue[key] = processValueFiles(value[key], onFileIdentified);\n\t\t}\n\t\treturn value;\n\t}\n\n\treturn value;\n}\n", "import { EventSubscriber, FileData } from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { Entity } from '../entities/Entity.js';\n\nexport type EntityFileEvents = {\n\tchange: () => void;\n};\n\nexport const UPDATE = Symbol('entity-file-update');\nexport const MARK_FAILED = Symbol('entity-file-mark-failed');\n\n// this one goes on Entity\nexport const CHILD_FILE_CHANGED = Symbol('child-file-changed');\n\nexport type EntityFileSnapshot = {\n\tid: string;\n\turl?: string | null;\n};\n\n/**\n * Provides a consistent interface for files used in an app via\n * Entity access.\n */\nexport class EntityFile extends EventSubscriber<EntityFileEvents> {\n\t// cached object URL for a local blob file, if applicable\n\tprivate _objectUrl: string | null = null;\n\tprivate _fileData: FileData | null = null;\n\tprivate _loading = true;\n\tprivate _failed = false;\n\tprivate _failedReason: string | undefined;\n\tprivate _downloadRemote = false;\n\tprivate _uploaded = false;\n\tprivate ctx: Context;\n\tprivate unsubscribes: (() => void)[] = [];\n\tprivate parent: Entity;\n\n\tconstructor(\n\t\tpublic readonly id: string,\n\t\t{\n\t\t\tdownloadRemote = false,\n\t\t\tctx,\n\t\t\tparent,\n\t\t}: {\n\t\t\tdownloadRemote?: boolean;\n\t\t\tctx: Context;\n\t\t\tparent: Entity;\n\t\t},\n\t) {\n\t\tsuper();\n\t\tthis.ctx = ctx;\n\t\tthis.parent = parent;\n\t\tthis._downloadRemote = downloadRemote;\n\n\t\tthis.unsubscribes.push(\n\t\t\tthis.ctx.internalEvents.subscribe(`fileUploaded:${id}`, this.onUploaded),\n\t\t);\n\t}\n\n\tget downloadRemote() {\n\t\treturn this._downloadRemote;\n\t}\n\tget isFile() {\n\t\treturn true;\n\t}\n\tget isUploaded() {\n\t\treturn this._uploaded || this._fileData?.remote || false;\n\t}\n\tget error() {\n\t\treturn this._failedReason || null;\n\t}\n\n\tprivate emitChange() {\n\t\tthis.parent[CHILD_FILE_CHANGED](this);\n\t\tthis.emit('change');\n\t}\n\n\t[UPDATE] = (fileData: FileData) => {\n\t\tthis.ctx.log('debug', 'EntityFile updated', this.id, fileData);\n\t\tthis._loading = false;\n\t\tthis._failed = false;\n\t\tthis._fileData = fileData;\n\t\tif (fileData.file) {\n\t\t\tif (this._objectUrl && 'revokeObjectURL' in URL) {\n\t\t\t\tURL.revokeObjectURL(this._objectUrl);\n\t\t\t}\n\t\t\tthis.ctx.log('debug', 'Creating object URL for file', this.id);\n\t\t\tthis._objectUrl = URL.createObjectURL(fileData.file);\n\t\t}\n\t\tthis.emitChange();\n\t};\n\n\t[MARK_FAILED] = (reason?: string) => {\n\t\tthis._failed = true;\n\t\tthis._failedReason = reason;\n\t\tthis._loading = false;\n\t\tthis.emitChange();\n\t};\n\n\tprivate onUploaded = (data: FileData) => {\n\t\t// TODO: cleanup all this uploaded flagging junk\n\t\tthis._fileData ??= data;\n\t\tthis._uploaded = true;\n\t\tthis.ctx.log('debug', 'File marked uploaded', this.id, this._fileData);\n\t\tthis.emitChange();\n\t};\n\n\tget url(): string | null {\n\t\t// prefer local file representations.\n\t\tif (this.loading) return null;\n\t\tif (this._objectUrl) return this._objectUrl;\n\t\t// TODO: use localPath here?\n\t\treturn this._fileData?.url ?? null;\n\t}\n\n\tget name(): string | null {\n\t\treturn this._fileData?.name ?? null;\n\t}\n\n\tget type(): string | null {\n\t\treturn this._fileData?.type ?? null;\n\t}\n\n\tget loading() {\n\t\treturn this._loading;\n\t}\n\n\tget failed() {\n\t\treturn this._failed;\n\t}\n\n\tdestroy = () => {\n\t\tif (this._objectUrl) {\n\t\t\tURL.revokeObjectURL(this._objectUrl);\n\t\t}\n\t\tthis.dispose();\n\t};\n\n\tgetSnapshot(): FileData {\n\t\treturn {\n\t\t\tid: this.id,\n\t\t\turl: this._fileData?.url ?? this._objectUrl ?? undefined,\n\t\t\tname: this.name ?? 'unknown-file',\n\t\t\tremote: this._fileData?.remote ?? false,\n\t\t\ttype: this.type ?? '',\n\t\t\tfile: this._fileData?.file,\n\t\t};\n\t}\n}\n", "import { ObjectIdentifier } from '@verdant-web/common';\nimport { Context } from '../internal.js';\nimport { Entity, EntityInit } from './Entity.js';\n\nexport class EntityCache {\n\tprivate ctx: Context;\n\tprivate cache = new Map<string, WeakRef<Entity>>();\n\n\tconstructor({ initial, ctx }: { initial?: Entity[]; ctx: Context }) {\n\t\tthis.ctx = ctx;\n\t\tif (initial) {\n\t\t\tfor (const entity of initial) {\n\t\t\t\tthis.cache.set(entity.oid, ctx.weakRef(entity));\n\t\t\t}\n\t\t}\n\t}\n\n\tget = (init: EntityInit): Entity => {\n\t\tconst cached = this.getCached(init.oid);\n\t\tif (cached) return cached;\n\t\tconst entity = new Entity(init);\n\t\tthis.cache.set(init.oid, this.ctx.weakRef(entity));\n\t\treturn entity;\n\t};\n\n\thas = (oid: ObjectIdentifier) => {\n\t\treturn this.cache.has(oid);\n\t};\n\n\tgetCached = (oid: string) => {\n\t\tif (this.cache.has(oid)) {\n\t\t\tconst ref = this.cache.get(oid);\n\t\t\tconst derefed = ref?.deref();\n\t\t\tif (derefed) {\n\t\t\t\treturn derefed as Entity;\n\t\t\t} else {\n\t\t\t\tthis.cache.delete(oid);\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t};\n}\n", "import { Entity } from './Entity.js';\nimport { EntityChangeInfo } from './types.js';\n\nexport function entityFieldSubscriber<T = any>(\n\tentity: Entity,\n\tfield: string | number | symbol,\n\tsubscriber: (\n\t\tnewValue: T,\n\t\tinfo: EntityChangeInfo & { previousValue: T },\n\t) => void,\n) {\n\tconst valueHolder = {\n\t\tpreviousValue: entity.get(field),\n\t\tisLocal: false,\n\t};\n\tfunction handler(\n\t\tthis: { previousValue: T } & EntityChangeInfo,\n\t\tinfo: EntityChangeInfo,\n\t) {\n\t\tif (entity.deleted) {\n\t\t\treturn;\n\t\t}\n\t\tconst newValue = entity.get(field);\n\t\tif (newValue !== this.previousValue) {\n\t\t\tthis.isLocal = info.isLocal;\n\t\t\tsubscriber(newValue, this);\n\t\t\tthis.previousValue = newValue;\n\t\t}\n\t}\n\treturn entity.subscribe('change', handler.bind(valueHolder));\n}\n", "import {\n\tEntityValidationProblem,\n\tEventSubscriber,\n\tObjectIdentifier,\n\tOperation,\n\tStorageFieldSchema,\n\tassert,\n\tassignOid,\n\tcloneDeep,\n\tcompareRefs,\n\tcreateFileRef,\n\tcreateRef,\n\tcreateSubOid,\n\tgetChildFieldSchema,\n\tgetFieldDefault,\n\thasDefault,\n\tisFile,\n\tisFileRef,\n\tisNullable,\n\tisObject,\n\tisObjectRef,\n\tisPrimitive,\n\tisRef,\n\tmaybeGetOid,\n\tmemoByKeys,\n\ttraverseCollectionFieldsAndApplyDefaults,\n\tvalidateEntityField,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { CHILD_FILE_CHANGED } from '../files/EntityFile.js';\nimport { FileManager } from '../files/FileManager.js';\nimport { processValueFiles } from '../files/utils.js';\nimport { ClientWithCollections, EntityFile } from '../index.js';\nimport { EntityCache } from './EntityCache.js';\nimport { EntityFamilyMetadata, EntityMetadataView } from './EntityMetadata.js';\nimport { EntityStoreEventData, EntityStoreEvents } from './EntityStore.js';\nimport { entityFieldSubscriber } from './entityFieldSubscriber.js';\nimport {\n\tAnyEntity,\n\tBaseEntityValue,\n\tDataFromInit,\n\tEntityChange,\n\tEntityEvents,\n\tListEntity,\n\tListItemInit,\n\tListItemValue,\n\tObjectEntity,\n} from './types.js';\n\nexport interface EntityInit {\n\toid: ObjectIdentifier;\n\tschema: StorageFieldSchema;\n\tentityFamily?: EntityCache;\n\tmetadataFamily: EntityFamilyMetadata;\n\tparent?: Entity;\n\tctx: Context;\n\tfiles: FileManager;\n\treadonlyKeys?: string[];\n\tfieldPath?: (string | number)[];\n\tstoreEvents: EntityStoreEvents;\n\tdeleteSelf: () => void;\n}\n\nconst PRIVATE_ENTITY_CONTEXT_KEY = Symbol('private entity context key');\n\nexport class Entity<\n\t\tInit = any,\n\t\tKeyValue extends BaseEntityValue = any,\n\t\tSnapshot extends any = DataFromInit<Init>,\n\t>\n\textends EventSubscriber<EntityEvents>\n\timplements\n\t\tObjectEntity<Init, KeyValue, Snapshot>,\n\t\tListEntity<Init, KeyValue, Snapshot>\n{\n\treadonly oid: ObjectIdentifier;\n\tprivate readonlyKeys: string[];\n\tprivate fieldPath: (string | number)[] = [];\n\t// these are shared between all entities in this family\n\tprivate entityFamily: EntityCache;\n\tprivate metadataFamily;\n\n\treadonly schema;\n\tprivate parent: Entity | undefined;\n\tprivate ctx;\n\tprivate files;\n\tprivate storeEvents;\n\n\tget [PRIVATE_ENTITY_CONTEXT_KEY]() {\n\t\treturn this.ctx;\n\t}\n\n\t// an internal representation of this Entity.\n\t// if present, this is the cached, known value. If null,\n\t// the entity is deleted. If undefined, we need to recompute\n\t// the view.\n\tprivate _viewData: EntityMetadataView | undefined = undefined;\n\tprivate validationError: EntityValidationProblem | undefined = undefined;\n\tprivate cachedDeepUpdatedAt: number | null = null;\n\t// only used for root entities to track delete/restore state.\n\tprivate wasDeletedLastChange = false;\n\tprivate cachedView: any | undefined = undefined;\n\t// provided from external creators, this is a method to delete\n\t// this entity.\n\tprivate _deleteSelf: () => void;\n\n\tconstructor({\n\t\toid,\n\t\tschema,\n\t\tentityFamily: childCache,\n\t\tparent,\n\t\tctx,\n\t\tmetadataFamily,\n\t\treadonlyKeys,\n\t\tfiles,\n\t\tstoreEvents,\n\t\tdeleteSelf,\n\t\tfieldPath,\n\t}: EntityInit) {\n\t\tsuper();\n\n\t\tassert(!!oid, 'oid is required');\n\n\t\tthis.oid = oid;\n\t\tthis.readonlyKeys = readonlyKeys || [];\n\t\tthis.ctx = ctx;\n\t\tthis.files = files;\n\t\tthis.schema = schema;\n\t\tthis.fieldPath = fieldPath || [];\n\t\tthis.entityFamily =\n\t\t\tchildCache ||\n\t\t\tnew EntityCache({\n\t\t\t\tinitial: [this],\n\t\t\t\tctx,\n\t\t\t});\n\t\tthis.metadataFamily = metadataFamily;\n\t\tthis.storeEvents = storeEvents;\n\t\tthis.parent = parent;\n\t\tthis._deleteSelf = deleteSelf;\n\n\t\t// TODO: should any but the root entity be listening to these?\n\t\tif (!this.parent) {\n\t\t\tstoreEvents.add.attach(this.onAdd);\n\t\t\tstoreEvents.replace.attach(this.onReplace);\n\t\t\tstoreEvents.resetAll.attach(this.onResetAll);\n\t\t}\n\t}\n\n\tprivate onAdd = (_store: any, data: EntityStoreEventData) => {\n\t\tif (data.oid === this.oid) {\n\t\t\tthis.addConfirmedData(data);\n\t\t}\n\t};\n\tprivate onReplace = (_store: any, data: EntityStoreEventData) => {\n\t\tif (data.oid === this.oid) {\n\t\t\tthis.replaceAllData(data);\n\t\t}\n\t};\n\tprivate onResetAll = () => {\n\t\tthis.resetAllData();\n\t};\n\n\tprivate get metadata() {\n\t\treturn this.metadataFamily.get(this.oid);\n\t}\n\n\tprivate get patchCreator() {\n\t\treturn this.ctx.patchCreator;\n\t}\n\n\t/**\n\t * The view of this Entity, not including nested\n\t * entities (that's the snapshot - see #getSnapshot())\n\t *\n\t * Nested entities are represented by refs.\n\t */\n\tprivate get viewData() {\n\t\tif (this._viewData === undefined) {\n\t\t\tthis._viewData = this.metadata.computeView();\n\t\t\tthis.validate();\n\t\t}\n\t\treturn this._viewData;\n\t}\n\n\t/** convenience getter for viewData.view */\n\tprivate get rawView() {\n\t\treturn this.viewData.view;\n\t}\n\n\t/**\n\t * An Entity's View includes the rendering of its underlying data,\n\t * connecting of children where refs were, and validation\n\t * and pruning according to schema.\n\t */\n\tprivate get view() {\n\t\tif (this.cachedView !== undefined) {\n\t\t\treturn this.cachedView;\n\t\t}\n\n\t\tif (this.viewData.deleted) {\n\t\t\treturn null;\n\t\t}\n\t\t// can't use invalid data - but this should be bubbled up to\n\t\t// a prune point\n\t\tconst rawView = this.rawView;\n\n\t\tconst viewIsWrongType =\n\t\t\t(!rawView && !isNullable(this.schema)) ||\n\t\t\t(this.schema.type === 'array' && !Array.isArray(rawView)) ||\n\t\t\t((this.schema.type === 'object' || this.schema.type === 'map') &&\n\t\t\t\t!isObject(rawView));\n\n\t\tif (viewIsWrongType) {\n\t\t\t// this will cover lists and maps, too.\n\t\t\tif (hasDefault(this.schema)) {\n\t\t\t\treturn getFieldDefault(this.schema);\n\t\t\t}\n\t\t\t// force null - invalid - will require parent prune\n\t\t\treturn null as any;\n\t\t}\n\n\t\tlet newView: any = this.isList ? [] : {};\n\t\tassignOid(newView, this.oid);\n\n\t\tif (Array.isArray(rawView)) {\n\t\t\tconst schema = getChildFieldSchema(this.schema, 0);\n\t\t\tif (!schema) {\n\t\t\t\t/**\n\t\t\t\t * PRUNE - this is a prune point. we can't continue\n\t\t\t\t * to render this data, so we'll just return [].\n\t\t\t\t * This skips the loop.\n\t\t\t\t */\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'error',\n\t\t\t\t\t'No child field schema for list entity.',\n\t\t\t\t\tthis.oid,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tfor (let i = 0; i < rawView.length; i++) {\n\t\t\t\t\tconst child = this.get(i);\n\t\t\t\t\tif (this.childIsNull(child) && !isNullable(schema)) {\n\t\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t\t'error',\n\t\t\t\t\t\t\t'Child missing in non-nullable field',\n\t\t\t\t\t\t\tthis.oid,\n\t\t\t\t\t\t\t'index:',\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// this item will be pruned.\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnewView.push(child);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (isObject(rawView)) {\n\t\t\t// iterate over known properties in object-type entities;\n\t\t\t// for maps, we just iterate over the keys.\n\t\t\tconst keys =\n\t\t\t\tthis.schema.type === 'object'\n\t\t\t\t\t? Object.keys(this.schema.properties)\n\t\t\t\t\t: Object.keys(rawView);\n\t\t\tfor (const key of keys) {\n\t\t\t\tconst schema = getChildFieldSchema(this.schema, key);\n\t\t\t\tif (!schema) {\n\t\t\t\t\t/**\n\t\t\t\t\t * PRUNE - this is a prune point. we can't continue\n\t\t\t\t\t * to render this data. If this is a map, it will be\n\t\t\t\t\t * pruned empty. Otherwise, prune moves upward.\n\t\t\t\t\t *\n\t\t\t\t\t * This exits the loop.\n\t\t\t\t\t */\n\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t'No child field schema for object entity at key',\n\t\t\t\t\t\tkey,\n\t\t\t\t\t);\n\t\t\t\t\tif (this.schema.type === 'map') {\n\t\t\t\t\t\t// it's valid to prune here if it's a map\n\t\t\t\t\t\tnewView = {};\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// otherwise prune moves upward\n\t\t\t\t\t\tnewView = null;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tconst child = this.get(key as any);\n\t\t\t\tif (this.childIsNull(child) && !isNullable(schema)) {\n\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t'Child entity is missing for non-nullable field',\n\t\t\t\t\t\tthis.oid,\n\t\t\t\t\t\t'key:',\n\t\t\t\t\t\tkey,\n\t\t\t\t\t);\n\t\t\t\t\tif (this.schema.type !== 'map') {\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * PRUNE - this is a prune point. we can't continue\n\t\t\t\t\t\t * to render this data. If this is a map, we can ignore\n\t\t\t\t\t\t * this value. Otherwise we must prune upward.\n\t\t\t\t\t\t * This exits the loop.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tnewView = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// special case - rewrite undefined fields to null\n\t\t\t\t\tif (isNullable(schema) && child === undefined) {\n\t\t\t\t\t\tnewView[key] = null;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnewView[key] = child;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.cachedView = newView;\n\t\treturn newView;\n\t}\n\n\tprivate childIsNull = (child: any) => {\n\t\tif (child instanceof Entity) {\n\t\t\tconst childView = child.view;\n\t\t\treturn childView === null || childView === undefined;\n\t\t}\n\t\treturn child === null || child === undefined;\n\t};\n\n\tget uid() {\n\t\treturn this.oid;\n\t}\n\n\tget deleted() {\n\t\treturn this.viewData.deleted || this.view === null;\n\t}\n\n\t/**\n\t * Doesn't compute view data; simply uses available cached\n\t * view info to determine deletion status.\n\t */\n\tprivate get quickDeleted() {\n\t\treturn this._viewData?.deleted || this.cachedView === null;\n\t}\n\n\tget invalid() {\n\t\treturn !!this.validate();\n\t}\n\n\t/**\n\t * Returns true if this or any child is invalid (pruned)\n\t */\n\tget deepInvalid(): boolean {\n\t\tif (this.invalid) return true;\n\t\tif (Array.isArray(this.rawView)) {\n\t\t\tfor (let i = 0; i < this.rawView.length; i++) {\n\t\t\t\tif (isObjectRef(this.rawView[i])) {\n\t\t\t\t\tconst child = this.getChild(i, this.rawView[i].id);\n\t\t\t\t\tif (child.deepInvalid) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (isObject(this.rawView)) {\n\t\t\tfor (const key in this.rawView) {\n\t\t\t\tif (isObjectRef(this.rawView[key])) {\n\t\t\t\t\tconst child = this.getChild(key, this.rawView[key].id);\n\t\t\t\t\tif (child.deepInvalid) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tget isList() {\n\t\t// have to turn TS off here as our two interfaces both implement\n\t\t// const values for this boolean.\n\t\treturn (\n\t\t\tthis.schema.type === 'array' || (Array.isArray(this.viewData.view) as any)\n\t\t);\n\t}\n\n\tget updatedAt() {\n\t\treturn this.viewData.updatedAt;\n\t}\n\n\tget deepUpdatedAt() {\n\t\tif (this.cachedDeepUpdatedAt) return this.cachedDeepUpdatedAt;\n\t\t// iterate over all children and take the latest timestamp\n\t\tlet latest: number | null = this.updatedAt;\n\t\tif (this.isList) {\n\t\t\tthis.forEach((child: any) => {\n\t\t\t\tif (child instanceof Entity) {\n\t\t\t\t\tconst childTimestamp = child.deepUpdatedAt;\n\t\t\t\t\tif (childTimestamp && (!latest || childTimestamp > latest)) {\n\t\t\t\t\t\tlatest = childTimestamp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tthis.values().forEach((child) => {\n\t\t\t\tif (child instanceof Entity) {\n\t\t\t\t\tconst childTimestamp = child.deepUpdatedAt;\n\t\t\t\t\tif (childTimestamp && (!latest || childTimestamp > latest)) {\n\t\t\t\t\t\tlatest = childTimestamp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tthis.cachedDeepUpdatedAt = latest;\n\t\treturn latest;\n\t}\n\n\t/**\n\t * @internal - this is relevant to Verdant's system, not users.\n\t *\n\t * Indicates whether this document is from an outdated version\n\t * of the schema - which means it cannot be used until it is upgraded.\n\t */\n\tget isOutdatedVersion(): boolean {\n\t\tif (this.parent) return this.parent.isOutdatedVersion;\n\t\treturn this.viewData.fromOlderVersion;\n\t}\n\n\t/**\n\t * Returns the storage namespace this entity came from. For example, if you\n\t * have multiple stores initialized from the same schema, you can use this\n\t * to figure out where an isolated entity was created / stored.\n\t */\n\tget namespace() {\n\t\treturn this.ctx.namespace;\n\t}\n\n\t/**\n\t * The authz string signifying the permissions this entity has.\n\t * On the client (where we are) it's only ever possible to see\n\t * an entity with either full access or access for the current\n\t * user.\n\t */\n\tget access() {\n\t\treturn this.viewData.authz;\n\t}\n\tget isAuthorized() {\n\t\treturn !!this.access;\n\t}\n\n\t/**\n\t * Introspects the schema of a child field of this entity.\n\t */\n\tgetFieldSchema = (key: any): StorageFieldSchema => {\n\t\tconst fieldSchema = getChildFieldSchema(this.schema, key);\n\t\tassert(fieldSchema, `No schema for key ${key}`);\n\t\treturn fieldSchema;\n\t};\n\n\t/**\n\t * Pruning - when entities have invalid children, we 'prune' that\n\t * data up to the nearest prunable point - a nullable field,\n\t * or a list.\n\t */\n\tprotected validate = memoByKeys(\n\t\t() => {\n\t\t\tthis.validationError =\n\t\t\t\tvalidateEntityField({\n\t\t\t\t\tfield: this.schema,\n\t\t\t\t\tvalue: this.rawView,\n\t\t\t\t\tfieldPath: this.fieldPath,\n\t\t\t\t\texpectRefs: true,\n\t\t\t\t}) ?? undefined;\n\t\t\treturn this.validationError;\n\t\t},\n\t\t() => [this.viewData],\n\t);\n\n\tprivate viewWithMappedChildren = (\n\t\tmapper: (child: Entity | EntityFile) => any,\n\t) => {\n\t\tconst view = this.view;\n\t\tif (!view) {\n\t\t\treturn null;\n\t\t}\n\t\tif (Array.isArray(view)) {\n\t\t\tconst mapped = view.map((value) => {\n\t\t\t\tif (value instanceof Entity || value instanceof EntityFile) {\n\t\t\t\t\treturn mapper(value);\n\t\t\t\t} else {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t});\n\t\t\tassignOid(mapped, this.oid);\n\t\t\treturn mapped;\n\t\t} else {\n\t\t\tconst mapped = Object.entries(view).reduce((acc, [key, value]) => {\n\t\t\t\tif (value instanceof Entity || value instanceof EntityFile) {\n\t\t\t\t\tacc[key as any] = mapper(value);\n\t\t\t\t} else {\n\t\t\t\t\tacc[key as any] = value;\n\t\t\t\t}\n\t\t\t\treturn acc;\n\t\t\t}, {} as any);\n\t\t\tassignOid(mapped, this.oid);\n\t\t\treturn mapped;\n\t\t}\n\t};\n\n\tprivate rawViewWithMappedChildren = (\n\t\tmapper: (child: Entity | EntityFile) => any,\n\t) => {\n\t\tconst view = this.rawView;\n\t\tif (!view) {\n\t\t\treturn null;\n\t\t}\n\t\tif (Array.isArray(view)) {\n\t\t\tconst mapped = view.map((value, i) => {\n\t\t\t\tif (isRef(value)) {\n\t\t\t\t\treturn mapper(this.getChild(i, value.id));\n\t\t\t\t} else {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t});\n\t\t\tassignOid(mapped, this.oid);\n\t\t\treturn mapped;\n\t\t} else {\n\t\t\tconst mapped = Object.entries(view).reduce((acc, [key, value]) => {\n\t\t\t\tif (isRef(value)) {\n\t\t\t\t\tacc[key as any] = mapper(this.getChild(key, value.id));\n\t\t\t\t} else {\n\t\t\t\t\tacc[key as any] = value;\n\t\t\t\t}\n\t\t\t\treturn acc;\n\t\t\t}, {} as any);\n\t\t\tassignOid(mapped, this.oid);\n\t\t\treturn mapped;\n\t\t}\n\t};\n\n\t/**\n\t * A current snapshot of this Entity's data, including nested\n\t * Entities.\n\t */\n\tgetSnapshot = (): any => {\n\t\treturn this.viewWithMappedChildren((child) => child.getSnapshot());\n\t};\n\n\t/**\n\t * A snapshot of this Entity with unpruned (invalid) data. This will\n\t * not conform to the entity schema and should be used carefully.\n\t *\n\t * Can be used to inspect or recover invalid, pruned data not\n\t * otherwise accessible.\n\t */\n\tgetUnprunedSnapshot = (): any => {\n\t\treturn this.rawViewWithMappedChildren((child) => {\n\t\t\tif (child instanceof EntityFile) return child.getSnapshot();\n\t\t\treturn child.getUnprunedSnapshot();\n\t\t});\n\t};\n\n\t// change management methods (internal use only)\n\tprivate addPendingOperations = (operations: Operation[]) => {\n\t\tthis.ctx.log(\n\t\t\t'debug',\n\t\t\t'Entity: adding pending operations',\n\t\t\tthis.oid,\n\t\t\toperations,\n\t\t);\n\n\t\t// special case -- if this entity is pruned, any changes we apply to it\n\t\t// will be in relation to 'exposed' pruned data, not the 'real world'\n\t\t// data that's backing it. That means those changes will produce unexpected\n\t\t// or further invalid results. To avoid this, we basically stamp in the\n\t\t// pruned version of this entity before proceeding.\n\t\t//\n\t\t// as an example of a failure mode without this check, consider a list:\n\t\t// [1, 2, <pruned>, 4, 5]\n\t\t// the user sees: [1, 2, 4, 5]\n\t\t// when they try to replace the item at index 2 with \"0\" (they see \"4\"), they\n\t\t// actually replace the invisible pruned item, resulting in [1, 2, 0, 4, 5]\n\t\t// being the result when they expected [1, 2, 0, 5].\n\t\t//\n\t\t// To \"stamp\" the data before applying user changes, we diff the snapshot\n\t\t// (which is the pruned version) with the current state of the entity.\n\t\tif (this.deepInvalid) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'warn',\n\t\t\t\t'Changes are being applied to a pruned entity. This means that the pruned version is being treated as the new baseline and any pruned invalid data is lost.',\n\t\t\t\tthis.oid,\n\t\t\t);\n\t\t\tthis.canonizePrunedVersion();\n\t\t}\n\n\t\tthis.applyPendingOperations(operations);\n\t};\n\n\t// naming is fuzzy here, but this method was split out from\n\t// addPendingOperations since that method also conditionally canonizes\n\t// the pruned snapshot, and I wanted to keep the actual insertion of\n\t// the ops in one place, so leaving it as part of addPendingOperations\n\t// would introduce infinite recursion when canonizing.\n\tprivate applyPendingOperations = (operations: Operation[]) => {\n\t\t// apply authz to all operations\n\t\tif (this.access) {\n\t\t\tfor (const op of operations) {\n\t\t\t\top.authz = this.access;\n\t\t\t}\n\t\t}\n\n\t\tconst changes = this.metadataFamily.addPendingData(operations);\n\t\tfor (const change of changes) {\n\t\t\tthis.change(change);\n\t\t}\n\t};\n\n\tprivate getPruneDiff = () => {\n\t\tconst snapshot = this.getSnapshot();\n\t\tconst unprunedSnapshot = this.getUnprunedSnapshot();\n\t\treturn this.patchCreator.createDiff(unprunedSnapshot, snapshot, {\n\t\t\tauthz: this.access,\n\t\t\tmerge: false,\n\t\t});\n\t};\n\tprivate canonizePrunedVersion = () => {\n\t\tthis.applyPendingOperations(this.getPruneDiff());\n\t};\n\n\tprivate addConfirmedData = (data: EntityStoreEventData) => {\n\t\tthis.ctx.log('debug', 'Entity: adding confirmed data', this.oid);\n\t\tconst changes = this.metadataFamily.addConfirmedData(data);\n\t\tfor (const change of changes) {\n\t\t\tthis.change(change);\n\t\t}\n\t};\n\n\tprivate replaceAllData = (data: EntityStoreEventData) => {\n\t\tthis.ctx.log('debug', 'Entity: replacing all data', this.oid);\n\t\tconst changes = this.metadataFamily.replaceAllData(data);\n\t\tfor (const change of changes) {\n\t\t\tthis.change(change);\n\t\t}\n\t};\n\n\tprivate resetAllData = () => {\n\t\tthis.ctx.log('debug', 'Entity: resetting all data', this.oid);\n\t\tthis.cachedDeepUpdatedAt = null;\n\t\tthis.cachedView = undefined;\n\t\tthis._viewData = undefined;\n\t\tconst changes = this.metadataFamily.replaceAllData({});\n\t\tfor (const change of changes) {\n\t\t\tthis.change(change);\n\t\t}\n\t};\n\n\tprivate invalidateCachedView = () => {\n\t\tthis._viewData = undefined;\n\t\tthis.cachedView = undefined;\n\t};\n\n\t// invalidates cached view of any entity targetted by change. this can\n\t// be called by any member of the tree and will automatically target\n\t// the correct entity.\n\tprivate invalidate = (ev: EntityChange) => {\n\t\tif (ev.oid === this.oid) {\n\t\t\tthis.invalidateCachedView();\n\t\t} else {\n\t\t\tconst other = this.entityFamily.getCached(ev.oid);\n\t\t\tif (other && other instanceof Entity) {\n\t\t\t\t// forward the invalidation to the correct family member.\n\t\t\t\tother.invalidate(ev);\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate change = (ev: EntityChange) => {\n\t\tif (ev.oid === this.oid) {\n\t\t\t// reset cached view\n\t\t\tthis.invalidateCachedView();\n\t\t\tif (!this.parent) {\n\t\t\t\tthis.changeRoot(ev);\n\t\t\t} else {\n\t\t\t\tthis.changeNested(ev);\n\t\t\t}\n\t\t} else {\n\t\t\t// forward it to the correct family member. if none exists\n\t\t\t// in cache, no one will hear it anyways.\n\t\t\tconst other = this.entityFamily.getCached(ev.oid);\n\t\t\tif (other && other instanceof Entity) {\n\t\t\t\tother.change(ev);\n\t\t\t}\n\t\t}\n\t};\n\tprivate changeRoot = (ev: EntityChange) => {\n\t\t// for root entities, we need to determine if we're deleted or not\n\t\t// before firing any events\n\t\tif (this.deleted) {\n\t\t\tif (!this.wasDeletedLastChange) {\n\t\t\t\tthis.ctx.log('debug', 'Entity deleted', this.oid);\n\t\t\t\tthis.emit('delete', { isLocal: ev.isLocal });\n\t\t\t\tthis.wasDeletedLastChange = true;\n\t\t\t} else {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'Entity already deleted, not emitting delete or change events',\n\t\t\t\t\tthis.oid,\n\t\t\t\t);\n\t\t\t\t// already deleted, do nothing.\n\t\t\t}\n\t\t} else {\n\t\t\tif (this.wasDeletedLastChange) {\n\t\t\t\tthis.ctx.log('debug', 'Entity restored', this.oid);\n\t\t\t\tthis.emit('restore', { isLocal: ev.isLocal });\n\t\t\t\tthis.wasDeletedLastChange = false;\n\t\t\t}\n\t\t\t// emit deepchange, too\n\t\t\tthis.deepChange(this, ev);\n\t\t\t// emit the change, it's for us\n\t\t\tthis.emit('change', { isLocal: ev.isLocal });\n\t\t}\n\t};\n\tprivate changeNested = (ev: EntityChange) => {\n\t\t// do not emit changes when deleted\n\t\tif (this.deleted) {\n\t\t\tthis.ctx.log('debug', 'Entity deleted, not emitting change', this.oid);\n\t\t\treturn;\n\t\t}\n\t\t// chain deepChanges to parents\n\t\tthis.deepChange(this, ev);\n\t\t// emit the change, it's for us\n\t\tthis.emit('change', { isLocal: ev.isLocal });\n\t};\n\tprotected deepChange = (target: Entity, ev: EntityChange) => {\n\t\tif (this.deleted) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'debug',\n\t\t\t\t'Entity deleted, not emitting deep change',\n\t\t\t\tthis.oid,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\t// reset cached deep updated at timestamp; either this\n\t\t// entity or children have changed\n\t\tthis.cachedDeepUpdatedAt = null;\n\t\t// reset this flag to recompute snapshot data - children\n\t\t// or self has changed. new pruning needs to happen.\n\t\tthis.cachedView = undefined;\n\t\tthis.emit('changeDeep', target, ev);\n\t\tthis.parent?.deepChange(target, ev);\n\t};\n\t[CHILD_FILE_CHANGED] = (file: EntityFile) => {\n\t\t// consistent with prior behavior, but kind of arbitrary.\n\t\tthis.deepChange(this, { isLocal: false, oid: this.oid });\n\t};\n\n\tprivate getChild = (key: any, oid: ObjectIdentifier) => {\n\t\tconst schema = getChildFieldSchema(this.schema, key);\n\t\tif (!schema) {\n\t\t\tthrow new Error(\n\t\t\t\t`No schema for key ${String(key)} in ${JSON.stringify(this.schema)}`,\n\t\t\t);\n\t\t}\n\t\treturn this.entityFamily.get({\n\t\t\toid,\n\t\t\tschema,\n\t\t\tentityFamily: this.entityFamily,\n\t\t\tmetadataFamily: this.metadataFamily,\n\t\t\tparent: this,\n\t\t\tctx: this.ctx,\n\t\t\tfiles: this.files,\n\t\t\tfieldPath: [...this.fieldPath, key],\n\t\t\tstoreEvents: this.storeEvents,\n\t\t\tdeleteSelf: this.delete.bind(this, key),\n\t\t});\n\t};\n\n\tsubscribeToField = <K extends keyof KeyValue>(\n\t\tkey: K,\n\t\tevent: 'change', // here to keep future api changes stable\n\t\tcallback: (\n\t\t\tvalue: KeyValue[K],\n\t\t\tinfo: { previousValue: KeyValue[K]; isLocal?: boolean },\n\t\t) => void,\n\t) => {\n\t\treturn entityFieldSubscriber<KeyValue[K]>(this, key, callback);\n\t};\n\n\t// generic entity methods\n\t/**\n\t * Gets a value from this Entity. If the value\n\t * is an object, it will be wrapped in another\n\t * Entity.\n\t */\n\tget = <Key extends keyof KeyValue>(key: Key): KeyValue[Key] => {\n\t\tassertNotSymbol(key);\n\n\t\tconst view = this.rawView;\n\t\tif (!view) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot access data at key ${key} on deleted entity ${this.oid}`,\n\t\t\t);\n\t\t}\n\t\tconst child = view[key as any];\n\t\tconst fieldSchema = getChildFieldSchema(this.schema, key);\n\t\tif (!fieldSchema) {\n\t\t\tthrow new Error(\n\t\t\t\t`No schema for key ${String(key)} in ${JSON.stringify(this.schema)}`,\n\t\t\t);\n\t\t}\n\t\tif (isRef(child)) {\n\t\t\tif (isFileRef(child)) {\n\t\t\t\tif (fieldSchema.type !== 'file') {\n\t\t\t\t\t// at least try to not fail\n\t\t\t\t\tif (isNullable(fieldSchema)) {\n\t\t\t\t\t\treturn null as KeyValue[Key];\n\t\t\t\t\t} else if (hasDefault(fieldSchema)) {\n\t\t\t\t\t\treturn getFieldDefault(fieldSchema) as KeyValue[Key];\n\t\t\t\t\t}\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Expected file schema for key ${String(key)}, got ${\n\t\t\t\t\t\t\tfieldSchema.type\n\t\t\t\t\t\t}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst file = this.files.get(child.id, {\n\t\t\t\t\tdownloadRemote: !!fieldSchema.downloadRemote,\n\t\t\t\t\tctx: this.ctx,\n\t\t\t\t\tparent: this,\n\t\t\t\t});\n\n\t\t\t\treturn file as KeyValue[Key];\n\t\t\t} else {\n\t\t\t\tif (fieldSchema.type === 'file') {\n\t\t\t\t\t// schema and child ref type do not match...\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`Expected file ref for key ${String(key)}, got ${child}`,\n\t\t\t\t\t);\n\t\t\t\t\t// at least try to not fail\n\t\t\t\t\tif (isNullable(fieldSchema)) {\n\t\t\t\t\t\treturn null as KeyValue[Key];\n\t\t\t\t\t} else if (hasDefault(fieldSchema)) {\n\t\t\t\t\t\treturn getFieldDefault(fieldSchema) as KeyValue[Key];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`No valid value for key ${String(key)} in ${JSON.stringify(this.schema)}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst childEntity = this.getChild(key, child.id);\n\t\t\t\tif (childEntity.deepInvalid) {\n\t\t\t\t\t// this child is pruned. materialize a pruned version of\n\t\t\t\t\t// this subtree if possible.\n\n\t\t\t\t\t// special case: lists -- as long as the list itself\n\t\t\t\t\t// is present and valid, it can omit invalid children\n\t\t\t\t\t// selectively rather than fallback to an empty default\n\t\t\t\t\tif (fieldSchema.type === 'array') {\n\t\t\t\t\t\treturn childEntity as KeyValue[Key];\n\t\t\t\t\t}\n\t\t\t\t\t// special case: maps -- similar to lists\n\t\t\t\t\tif (fieldSchema.type === 'map') {\n\t\t\t\t\t\treturn childEntity as KeyValue[Key];\n\t\t\t\t\t}\n\t\t\t\t\tif (isNullable(fieldSchema)) {\n\t\t\t\t\t\treturn null as KeyValue[Key];\n\t\t\t\t\t}\n\t\t\t\t\tif (hasDefault(fieldSchema)) {\n\t\t\t\t\t\tconst unprunedSnapshot = childEntity.getUnprunedSnapshot();\n\t\t\t\t\t\tconst pruneDiff = this.patchCreator.createDiff(\n\t\t\t\t\t\t\tunprunedSnapshot,\n\t\t\t\t\t\t\tgetFieldDefault(fieldSchema),\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmerge: false,\n\t\t\t\t\t\t\t\tmergeUnknownObjects: true,\n\t\t\t\t\t\t\t\tauthz: this.access,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn this.processPrunedChild(key, childEntity, pruneDiff);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn childEntity as KeyValue[Key];\n\t\t\t}\n\t\t} else {\n\t\t\t// if this is a Map type, a missing child is\n\t\t\t// just an empty spot\n\t\t\tif (this.schema.type === 'map' && child === undefined) {\n\t\t\t\treturn undefined as KeyValue[Key];\n\t\t\t}\n\t\t\t// prune invalid primitive fields\n\t\t\tif (\n\t\t\t\tvalidateEntityField({\n\t\t\t\t\tfield: fieldSchema,\n\t\t\t\t\tvalue: child,\n\t\t\t\t\tfieldPath: [...this.fieldPath, key],\n\t\t\t\t\tdepth: 1,\n\t\t\t\t\trequireDefaults: true,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tif (hasDefault(fieldSchema)) {\n\t\t\t\t\t// primitive fields with defaults are easy.\n\t\t\t\t\tif (isPrimitive(fieldSchema)) {\n\t\t\t\t\t\treturn getFieldDefault(fieldSchema) as KeyValue[Key];\n\t\t\t\t\t}\n\n\t\t\t\t\t// object/list fields are hard.\n\t\t\t\t\tconst defaultValue = getFieldDefault(fieldSchema);\n\t\t\t\t\tconst prunedFieldOid = createSubOid(this.oid);\n\t\t\t\t\tconst pruneDiff = this.patchCreator.createInitialize(\n\t\t\t\t\t\tdefaultValue,\n\t\t\t\t\t\tprunedFieldOid,\n\t\t\t\t\t\tthis.access,\n\t\t\t\t\t);\n\t\t\t\t\tpruneDiff.push(\n\t\t\t\t\t\t...this.patchCreator.createSet(\n\t\t\t\t\t\t\tthis.oid,\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\tcreateRef(prunedFieldOid),\n\t\t\t\t\t\t\tthis.access,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t\tconst childEntity = this.getChild(key, prunedFieldOid);\n\t\t\t\t\treturn this.processPrunedChild(key, childEntity, pruneDiff);\n\t\t\t\t} else {\n\t\t\t\t\t// failure / hard prune: no way to represent this\n\t\t\t\t\t// data in a valid way exists. the parent entity\n\t\t\t\t\t// is also invalid and this should bubble up.\n\t\t\t\t\treturn undefined as KeyValue[Key];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn child as KeyValue[Key];\n\t\t}\n\t};\n\n\tprivate processPrunedChild = (\n\t\tkey: any,\n\t\tchild: Entity,\n\t\tpruneDiff: Operation[],\n\t): any => {\n\t\tthis.ctx.log(\n\t\t\t'warn',\n\t\t\t'Replacing invalid child object field with ephemeral, valid data',\n\t\t\tthis.oid,\n\t\t\tkey,\n\t\t);\n\t\tconst changes = this.metadataFamily.addEphemeralData(pruneDiff);\n\t\tfor (const change of changes) {\n\t\t\tthis.invalidate(change);\n\t\t}\n\t\treturn child as any;\n\t};\n\n\t/**\n\t * Gets a value on this entity. If the value is not\n\t * present, it will be set to the provided default\n\t * and returned synchronously. This method only sets\n\t * a new value once when a field is empty; subsequent\n\t * calls will retrieve the created value until it is\n\t * deleted.\n\t *\n\t * Note that this should only be called for nullable\n\t * fields. If the field is not nullable, the existing\n\t * value or the default value will always be returned,\n\t * and the default will not be set.\n\t */\n\tgetOrSet = <Key extends keyof Init & keyof KeyValue>(\n\t\tkey: Key,\n\t\tinit: Init[Key],\n\t): KeyValue[Key] => {\n\t\tassertNotSymbol(key);\n\t\tconst existing = this.get(key);\n\t\tif (existing) return existing;\n\t\tthis.set(key as any, init);\n\t\treturn this.get(key);\n\t};\n\n\tprivate processInputValue = (value: any, key: any) => {\n\t\tif (this.readonlyKeys.includes(key as string)) {\n\t\t\tthrow new Error(`Cannot set readonly key ${key.toString()}`);\n\t\t}\n\t\t// disassociate incoming OIDs on values and generally break object\n\t\t// references. cloning doesn't work on files so those are\n\t\t// filtered out.\n\t\t// The goal here is to be safe about a bunch of cases that could\n\t\t// result in corrupt data, like...\n\t\t// ent1.set('objField', ent2.get('objField'))\n\t\t// or\n\t\t// var shared = { foo: 'bar' };\n\t\t// ent1.set('objField', shared);\n\t\t// ent2.set('objField', shared);\n\t\t// ... each of these would result in the same object being\n\t\t// referenced in multiple entities, which could mean introduction\n\t\t// of foreign OIDs, or one object being assigned different OIDs\n\t\t// with unexpected results.\n\t\tif (!isFile(value)) {\n\t\t\tvalue = cloneDeep(value, false);\n\t\t}\n\t\tconst fieldSchema = getChildFieldSchema(this.schema, key);\n\t\tif (fieldSchema) {\n\t\t\ttraverseCollectionFieldsAndApplyDefaults(value, fieldSchema);\n\t\t\tconst validationError = validateEntityField({\n\t\t\t\tfield: fieldSchema,\n\t\t\t\tvalue,\n\t\t\t\tfieldPath: [...this.fieldPath, key],\n\t\t\t});\n\t\t\tif (validationError) {\n\t\t\t\t// TODO: is it a good idea to throw an error here? a runtime error won't be that helpful,\n\t\t\t\t// but also we don't really want invalid data supplied.\n\t\t\t\tthrow new Error(`Validation error: ${validationError.message}`, {\n\t\t\t\t\tcause: validationError,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn processValueFiles(value, (file) => this.files.add(file, this));\n\t};\n\n\tprivate getDeleteMode = (key: any) => {\n\t\tif (this.readonlyKeys.includes(key)) {\n\t\t\treturn false;\n\t\t}\n\t\t// any is always deletable, and map values\n\t\tif (this.schema.type === 'any' || this.schema.type === 'map') {\n\t\t\treturn 'delete';\n\t\t}\n\n\t\tif (this.schema.type === 'object') {\n\t\t\tconst property = this.schema.properties[key];\n\t\t\tif (!property) {\n\t\t\t\t// huh, the property doesn't exist. it's ok to\n\t\t\t\t// remove I suppose.\n\t\t\t\treturn 'delete';\n\t\t\t}\n\t\t\tif (property.type === 'any') return 'delete';\n\t\t\t// map can't be nullable. should it be?\n\t\t\tif (property.type === 'map') return false;\n\t\t\tif (property.nullable) return 'null';\n\t\t}\n\t\t// no other types are deletable\n\t\treturn false;\n\t};\n\n\t/**\n\t * Returns the referent value of an item in the list, used for\n\t * operations which act on items. if the item is an object,\n\t * it will attempt to create an OID reference to it. If it\n\t * is a primitive, it will return the primitive.\n\t */\n\tprivate getItemRefValue = (item: any) => {\n\t\tif (item instanceof Entity) {\n\t\t\treturn createRef(item.oid);\n\t\t}\n\t\tif (item instanceof EntityFile) {\n\t\t\treturn createFileRef(item.id);\n\t\t}\n\t\tif (typeof item === 'object') {\n\t\t\tconst itemOid = maybeGetOid(item);\n\t\t\tif (!itemOid || !this.entityFamily.has(itemOid)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot move object ${JSON.stringify(\n\t\t\t\t\t\titem,\n\t\t\t\t\t)} which does not exist in this list`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn createRef(itemOid);\n\t\t} else {\n\t\t\treturn item;\n\t\t}\n\t};\n\n\tset = (\n\t\tkey: any,\n\t\tvalue: any,\n\t\toptions?: {\n\t\t\t/**\n\t\t\t * Forces the creation of a change for this set even if the value is the same\n\t\t\t * as the current value for this key. This has an effect in situations where\n\t\t\t * offline changes from others are interleaved with local changes; when setting\n\t\t\t * a value to its current value (force=true), if that value were retroactively changed from\n\t\t\t * offline changes, the set would put it back to the value specified. If the\n\t\t\t * set is ignored because the value is the same (force=false), then retroactive\n\t\t\t * changes will be preserved.\n\t\t\t */\n\t\t\tforce: boolean;\n\t\t},\n\t) => {\n\t\tassertNotSymbol(key);\n\t\tif (!options?.force && this.get(key) === value) return;\n\n\t\tif (this.isList) {\n\t\t\tthis.addPendingOperations(\n\t\t\t\tthis.patchCreator.createListSet(\n\t\t\t\t\tthis.oid,\n\t\t\t\t\tkey,\n\t\t\t\t\tthis.processInputValue(value, key),\n\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.addPendingOperations(\n\t\t\t\tthis.patchCreator.createSet(\n\t\t\t\t\tthis.oid,\n\t\t\t\t\tkey,\n\t\t\t\t\tthis.processInputValue(value, key),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t};\n\n\t/**\n\t * Returns a destructured version of this Entity, where child\n\t * Entities are accessible at their respective keys.\n\t */\n\tgetAll = (): KeyValue => {\n\t\treturn this.view;\n\t};\n\n\tdelete = (key: any) => {\n\t\tif (this.isList) {\n\t\t\tassertNumber(key);\n\t\t\tthis.addPendingOperations(\n\t\t\t\tthis.patchCreator.createListDelete(this.oid, key),\n\t\t\t);\n\t\t} else {\n\t\t\t// the key must be deletable - i.e. optional in the schema.\n\t\t\tconst deleteMode = this.getDeleteMode(key);\n\t\t\tif (!deleteMode) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot delete key ${key.toString()} - the property is not marked as optional in the schema.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (deleteMode === 'delete') {\n\t\t\t\tthis.addPendingOperations(\n\t\t\t\t\tthis.patchCreator.createRemove(this.oid, key),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.addPendingOperations(\n\t\t\t\t\tthis.patchCreator.createSet(this.oid, key, null),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t};\n\n\t// object entity methods\n\tkeys = (): string[] => {\n\t\tif (!this.view) return [];\n\t\treturn Object.keys(this.view);\n\t};\n\n\tentries = (): [string, Exclude<KeyValue[keyof KeyValue], undefined>][] => {\n\t\tif (!this.view) return [];\n\t\treturn Object.entries(this.view);\n\t};\n\n\tvalues = (): Exclude<KeyValue[keyof KeyValue], undefined>[] => {\n\t\tif (!this.view) return [];\n\t\treturn Object.values(this.view);\n\t};\n\n\tget size() {\n\t\tif (this.isList) {\n\t\t\treturn this.length;\n\t\t}\n\t\treturn this.keys().length;\n\t}\n\n\tupdate = (\n\t\tdata: any,\n\t\t{\n\t\t\tmerge = true,\n\t\t\treplaceSubObjects = false,\n\t\t\tpreserveUndefined = false,\n\t\t\tdangerouslyDisableMerge = false,\n\t\t}: {\n\t\t\treplaceSubObjects?: boolean;\n\t\t\tmerge?: boolean;\n\t\t\tpreserveUndefined?: boolean;\n\t\t\tdangerouslyDisableMerge?: boolean;\n\t\t} = {},\n\t): void => {\n\t\tif (\n\t\t\t!merge &&\n\t\t\t!dangerouslyDisableMerge &&\n\t\t\tthis.schema.type !== 'any' &&\n\t\t\tthis.schema.type !== 'map'\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t'Cannot use .update without merge if the field has a strict schema type. merge: false is only available on \"any\" or \"map\" types.',\n\t\t\t);\n\t\t}\n\t\tconst changes: any = {};\n\t\tassignOid(changes, this.oid);\n\t\tfor (const [key, field] of Object.entries(data)) {\n\t\t\tif (this.readonlyKeys.includes(key as any)) {\n\t\t\t\tthrow new Error(`Cannot set readonly key ${key.toString()}`);\n\t\t\t}\n\t\t\t// ignore undefined values unless overridden\n\t\t\tif (field === undefined && !preserveUndefined) continue;\n\n\t\t\tconst fieldSchema = getChildFieldSchema(this.schema, key);\n\t\t\tif (fieldSchema) {\n\t\t\t\ttraverseCollectionFieldsAndApplyDefaults(field, fieldSchema);\n\t\t\t}\n\t\t\tchanges[key] = this.processInputValue(field, key);\n\t\t}\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createDiff(this.getSnapshot(), changes, {\n\t\t\t\tmergeUnknownObjects: !replaceSubObjects,\n\t\t\t\tmerge,\n\t\t\t}),\n\t\t);\n\t};\n\n\t// array entity methods\n\tget length(): number {\n\t\treturn this.view.length;\n\t}\n\n\tpush = (value: ListItemInit<Init>): void => {\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createListPush(\n\t\t\t\tthis.oid,\n\t\t\t\tthis.processInputValue(value, this.view.length),\n\t\t\t),\n\t\t);\n\t};\n\n\tinsert = (index: number, value: ListItemInit<Init>): void => {\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createListInsert(\n\t\t\t\tthis.oid,\n\t\t\t\tindex,\n\t\t\t\tthis.processInputValue(value, index),\n\t\t\t),\n\t\t);\n\t};\n\n\tmove = (from: number, to: number): void => {\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createListMoveByIndex(this.oid, from, to),\n\t\t);\n\t};\n\n\tmoveItem = (item: ListItemValue<KeyValue>, to: number): void => {\n\t\tconst itemRef = this.getItemRefValue(item);\n\t\tif (isRef(itemRef)) {\n\t\t\tthis.addPendingOperations(\n\t\t\t\tthis.patchCreator.createListMoveByRef(this.oid, itemRef, to),\n\t\t\t);\n\t\t} else {\n\t\t\tconst index = this.view.indexOf(item);\n\t\t\tif (index === -1) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot move item ${JSON.stringify(\n\t\t\t\t\t\titem,\n\t\t\t\t\t)} which does not exist in this list`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.move(index, to);\n\t\t}\n\t};\n\n\tadd = (value: ListItemValue<KeyValue>): void => {\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createListAdd(\n\t\t\t\tthis.oid,\n\t\t\t\tthis.processInputValue(value, this.view.length),\n\t\t\t),\n\t\t);\n\t};\n\n\tremoveAll = (item: ListItemValue<KeyValue>): void => {\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createListRemove(this.oid, this.getItemRefValue(item)),\n\t\t);\n\t};\n\n\tremoveFirst = (item: ListItemValue<KeyValue>): void => {\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createListRemove(\n\t\t\t\tthis.oid,\n\t\t\t\tthis.getItemRefValue(item),\n\t\t\t\t'first',\n\t\t\t),\n\t\t);\n\t};\n\n\tremoveLast = (item: ListItemValue<KeyValue>): void => {\n\t\tthis.addPendingOperations(\n\t\t\tthis.patchCreator.createListRemove(\n\t\t\t\tthis.oid,\n\t\t\t\tthis.getItemRefValue(item),\n\t\t\t\t'last',\n\t\t\t),\n\t\t);\n\t};\n\n\t// list implements an iterator which maps items to wrapped\n\t// versions\n\t[Symbol.iterator]() {\n\t\tlet index = 0;\n\t\tlet length = this.view?.length;\n\t\treturn {\n\t\t\tnext: () => {\n\t\t\t\tif (index < length) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tvalue: this.get(index++) as ListItemValue<KeyValue>,\n\t\t\t\t\t\tdone: false,\n\t\t\t\t\t} as const;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tvalue: undefined,\n\t\t\t\t\tdone: true,\n\t\t\t\t} as const;\n\t\t\t},\n\t\t};\n\t}\n\n\tmap = <U>(\n\t\tcallback: (value: ListItemValue<KeyValue>, index: number) => U,\n\t): U[] => {\n\t\treturn this.view.map(callback);\n\t};\n\n\tfilter = (\n\t\tcallback: (value: ListItemValue<KeyValue>, index: number) => boolean,\n\t): ListItemValue<KeyValue>[] => {\n\t\treturn this.view.filter(callback);\n\t};\n\n\thas = (value: ListItemValue<KeyValue>): boolean => {\n\t\tif (!this.isList) {\n\t\t\tthrow new Error('has() is only available on list entities');\n\t\t}\n\t\tconst itemRef = this.getItemRefValue(value);\n\t\tif (isRef(itemRef)) {\n\t\t\treturn this.view.some((item: any) => {\n\t\t\t\tif (isRef(item)) {\n\t\t\t\t\treturn compareRefs(item, itemRef);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\treturn this.view.includes(value);\n\t\t}\n\t};\n\n\tforEach = (\n\t\tcallback: (value: ListItemValue<KeyValue>, index: number) => void,\n\t): void => {\n\t\tthis.view.forEach(callback);\n\t};\n\n\treduce = <U>(\n\t\tcallback: (\n\t\t\tpreviousValue: U,\n\t\t\tcurrentValue: ListItemValue<KeyValue>,\n\t\t\tindex: number,\n\t\t) => U,\n\t\tinitialValue: U,\n\t): U => {\n\t\treturn this.view.reduce(callback, initialValue);\n\t};\n\n\tsome = (predicate: (value: ListItemValue<KeyValue>) => boolean): boolean => {\n\t\treturn this.view.some(predicate);\n\t};\n\n\tevery = (predicate: (value: ListItemValue<KeyValue>) => boolean): boolean => {\n\t\treturn this.view.every(predicate);\n\t};\n\n\tfind = (\n\t\tpredicate: (value: ListItemValue<KeyValue>) => boolean,\n\t): ListItemValue<KeyValue> | undefined => {\n\t\treturn this.view.find(predicate);\n\t};\n\n\tincludes = this.has;\n\n\t/**\n\t * Deletes this entity. WARNING: this can be tricky to\n\t * use correctly. You must not reference this entity\n\t * instance in any way after the deletion happens, or\n\t * you will get an error!\n\t *\n\t * It's a little easier to delete using client.delete\n\t * if you can manage it with your app's code. For example,\n\t * in React, use hooks.useClient() to get the client and\n\t * call delete from there.\n\t */\n\tdeleteSelf = () => {\n\t\treturn this._deleteSelf();\n\t};\n\n\t// TODO: make these escape hatches unnecessary\n\t__getViewData__ = (oid: ObjectIdentifier, type: 'confirmed' | 'pending') => {\n\t\treturn this.metadataFamily.get(oid).computeView(type === 'confirmed');\n\t};\n\t__getFamilyOids__ = () => this.metadataFamily.getAllOids();\n\n\t__discardPendingOperation__ = (operation: Operation) => {\n\t\tthis.metadataFamily.discardPendingOperation(operation);\n\t\tthis.invalidateCachedView();\n\t};\n}\n\nfunction assertNotSymbol<T>(key: T): asserts key is Exclude<T, symbol> {\n\tif (typeof key === 'symbol') throw new Error(\"Symbol keys aren't supported\");\n}\n\nfunction assertNumber(key: unknown): asserts key is number {\n\tif (typeof key !== 'number')\n\t\tthrow new Error('Only number keys are supported in list entities');\n}\n\nexport function getEntityClient(\n\tentity: AnyEntity<any, any, any>,\n): ClientWithCollections {\n\treturn (entity as Entity)[\n\t\tPRIVATE_ENTITY_CONTEXT_KEY\n\t].getClient() as ClientWithCollections;\n}\n", "import {\n\tAuthorizationKey,\n\tDocumentBaseline,\n\tObjectIdentifier,\n\tOperation,\n\tapplyPatch,\n\tareOidsRelated,\n\tassert,\n\tassignOid,\n\tcloneDeep,\n\tcompareTimestampSchemaVersions,\n\tgetWallClockTime,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { EntityChange } from './types.js';\n\nexport type EntityMetadataView = {\n\tview: any;\n\tfromOlderVersion: boolean;\n\tdeleted: boolean;\n\tempty: boolean;\n\tupdatedAt: number;\n\tlatestTimestamp: string | null;\n\tauthz?: AuthorizationKey;\n};\n\nexport class EntityMetadata {\n\tprivate ctx;\n\tprivate baseline: DocumentBaseline | null = null;\n\t// these must be kept in timestamp order.\n\tprivate confirmedOperations: Operation[] = [];\n\t// operations applied locally, but not sent to persistence\n\t// until 'committed' by pending operations. this powers the\n\t// self-healing pruning system, which injects these ephemeral\n\t// operations to materialize pruned 'fixed' data in place of\n\t// 'real' invalid data so the user can keep using the app. as\n\t// soon as the user makes modifications to the entity, this\n\t// ephemeral pruned data is applied underneath it.\n\tprivate ephemeralOperations?: Operation[] = [];\n\tprivate pendingOperations: Operation[] = [];\n\treadonly oid;\n\n\tconstructor({\n\t\toid,\n\t\tctx,\n\t\tconfirmedOperations,\n\t\tpendingOperations,\n\t\tbaseline,\n\t}: {\n\t\toid: ObjectIdentifier;\n\t\tctx: Context;\n\t\tconfirmedOperations?: Operation[];\n\t\tpendingOperations?: Operation[];\n\t\tbaseline?: DocumentBaseline;\n\t}) {\n\t\tassert(oid, 'oid is required');\n\t\tthis.ctx = ctx;\n\t\tthis.oid = oid;\n\t\tif (confirmedOperations) {\n\t\t\tthis.confirmedOperations = confirmedOperations;\n\t\t}\n\t\tif (pendingOperations) {\n\t\t\tthis.pendingOperations = pendingOperations;\n\t\t}\n\t\tif (baseline) {\n\t\t\tthis.baseline = baseline;\n\t\t}\n\t}\n\n\t/**\n\t * Compute the current view of the entity.\n\t */\n\tcomputeView = (omitPending = false): EntityMetadataView => {\n\t\tconst base = cloneDeep(this.baseline?.snapshot ?? undefined);\n\t\tconst baselineTimestamp = this.baseline?.timestamp ?? null;\n\n\t\t// start with the baseline authz, if any. further init ops\n\t\t// may overwrite this.\n\t\tlet authz = this.baseline?.authz;\n\n\t\tconst confirmedResult = this.applyOperations(\n\t\t\t// apply ops to baseline\n\t\t\tbase,\n\t\t\t// deleted if there's no baseline\n\t\t\t!base,\n\t\t\t// we're applying confirmed ops first\n\t\t\tthis.confirmedOperations,\n\t\t\t// latest timestamp is the baseline timestamp, if any\n\t\t\tbaselineTimestamp,\n\t\t\t// only apply ops after the baseline timestamp\n\t\t\tbaselineTimestamp,\n\t\t);\n\t\t// now's the time to declare we saw the future if we did.\n\t\tif (confirmedResult.futureSeen) {\n\t\t\tthis.ctx.globalEvents.emit('futureSeen', confirmedResult.futureSeen);\n\t\t}\n\t\tif (confirmedResult.authz) {\n\t\t\tauthz = confirmedResult.authz;\n\t\t}\n\n\t\tconst ephemeralResult =\n\t\t\t!this.ephemeralOperations || omitPending\n\t\t\t\t? confirmedResult\n\t\t\t\t: this.applyOperations(\n\t\t\t\t\t\tconfirmedResult.view,\n\t\t\t\t\t\tconfirmedResult.deleted,\n\t\t\t\t\t\tthis.ephemeralOperations,\n\t\t\t\t\t\tconfirmedResult.latestTimestamp,\n\t\t\t\t\t\tnull,\n\t\t\t\t\t);\n\n\t\tconst pendingResult = omitPending\n\t\t\t? confirmedResult\n\t\t\t: this.applyOperations(\n\t\t\t\t\tephemeralResult.view,\n\t\t\t\t\tephemeralResult.deleted,\n\t\t\t\t\t// now we're applying pending operations\n\t\t\t\t\tthis.pendingOperations,\n\t\t\t\t\t// keep our latest timestamp up to date\n\t\t\t\t\tephemeralResult.latestTimestamp,\n\t\t\t\t\t// we don't use after for pending ops, they're all\n\t\t\t\t\t// logically in the future\n\t\t\t\t\tnull,\n\t\t\t\t);\n\t\tif (pendingResult.authz) {\n\t\t\tauthz = pendingResult.authz;\n\t\t}\n\n\t\t// before letting this data out into the wild, we need\n\t\t// to associate its oid\n\t\tif (pendingResult.view) {\n\t\t\tassignOid(pendingResult.view, this.oid);\n\t\t}\n\n\t\t// note whether confirmed data has an operation/baseline from the current\n\t\t// schema or not.\n\t\tconst fromOlderVersion =\n\t\t\t!!confirmedResult.latestTimestamp &&\n\t\t\tcompareTimestampSchemaVersions(\n\t\t\t\tconfirmedResult.latestTimestamp,\n\t\t\t\tthis.ctx.time.now,\n\t\t\t) < 0;\n\n\t\tconst empty =\n\t\t\t!this.baseline &&\n\t\t\t!this.pendingOperations.length &&\n\t\t\t!this.confirmedOperations.length;\n\t\tif (empty) {\n\t\t\tthis.ctx.log('warn', `Tried to load Entity ${this.oid} with no data`);\n\t\t}\n\n\t\tconst updatedAtTimestamp =\n\t\t\tpendingResult.latestTimestamp ??\n\t\t\tconfirmedResult.latestTimestamp ??\n\t\t\tbaselineTimestamp;\n\t\tconst updatedAt = updatedAtTimestamp\n\t\t\t? getWallClockTime(updatedAtTimestamp)\n\t\t\t: 0;\n\n\t\tif (!pendingResult.view && !pendingResult.deleted && !empty) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'warn',\n\t\t\t\t`Entity ${this.oid} has no view, no deleted flag, and not empty`,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tview: pendingResult.view ?? undefined,\n\t\t\tdeleted: pendingResult.deleted,\n\t\t\tempty,\n\t\t\tfromOlderVersion,\n\t\t\tupdatedAt,\n\t\t\tlatestTimestamp: updatedAtTimestamp,\n\t\t\tauthz,\n\t\t};\n\t};\n\n\taddBaseline = (baseline: DocumentBaseline): void => {\n\t\t// opt out if our baseline is newer\n\t\tif (this.baseline && this.baseline.timestamp >= baseline.timestamp) {\n\t\t\treturn;\n\t\t}\n\t\tthis.baseline = baseline;\n\t\t// we can now drop any confirmed ops older than the baseline\n\t\twhile (this.confirmedOperations[0]?.timestamp < baseline.timestamp) {\n\t\t\tthis.confirmedOperations.shift();\n\t\t}\n\t};\n\n\t/**\n\t * @returns total number of new operations added\n\t */\n\taddConfirmedOperations = (operations: Operation[]): number => {\n\t\tlet totalAdded = 0;\n\t\t// the operations must be inserted in timestamp order\n\t\tfor (const op of operations) {\n\t\t\tconst index = this.confirmedOperations.findIndex(\n\t\t\t\t(o) => o.timestamp >= op.timestamp,\n\t\t\t);\n\t\t\tif (index !== -1) {\n\t\t\t\t// ensure we don't have a duplicate\n\t\t\t\tif (this.confirmedOperations[index].timestamp !== op.timestamp) {\n\t\t\t\t\t// otherwise, insert at the right place\n\t\t\t\t\tthis.confirmedOperations.splice(index, 0, op);\n\t\t\t\t\ttotalAdded++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// otherwise, append\n\t\t\t\tthis.confirmedOperations.push(op);\n\t\t\t\ttotalAdded++;\n\t\t\t}\n\t\t\t// FIXME: seems inefficient\n\t\t\t// remove this incoming op from pending if it's in there\n\t\t\tconst pendingPrior = this.pendingOperations.length;\n\t\t\tthis.discardPendingOperation(op);\n\t\t\ttotalAdded -= pendingPrior - this.pendingOperations.length;\n\t\t}\n\t\treturn totalAdded;\n\t};\n\n\taddPendingOperation = (operation: Operation) => {\n\t\tthis.pendingOperations.push(operation);\n\t};\n\n\taddEphemeralOperation = (operation: Operation) => {\n\t\tif (!this.ephemeralOperations) {\n\t\t\tthis.ephemeralOperations = [];\n\t\t}\n\t\tthis.ephemeralOperations.push(operation);\n\t};\n\n\tclearEphemeralOperations = () => {\n\t\tconst old = this.ephemeralOperations;\n\t\tthis.ephemeralOperations = [];\n\t\treturn old;\n\t};\n\n\tdiscardPendingOperation = (operation: Operation) => {\n\t\tthis.pendingOperations = this.pendingOperations.filter(\n\t\t\t(op) => op.timestamp !== operation.timestamp,\n\t\t);\n\t};\n\n\tprivate applyOperations = (\n\t\tbase: any,\n\t\tdeleted: boolean,\n\t\toperations: Operation[],\n\t\tlatestTimestamp: string | null,\n\t\tafter: string | null,\n\t): {\n\t\tview: any;\n\t\tlatestTimestamp: string | null;\n\t\tdeleted: boolean;\n\t\tfutureSeen: string | undefined;\n\t\tauthz?: AuthorizationKey;\n\t} => {\n\t\tlet futureSeen: string | undefined = undefined;\n\t\tlet authz: AuthorizationKey | undefined = undefined;\n\n\t\tconst now = this.ctx.time.now;\n\t\tfor (const op of operations) {\n\t\t\t// ignore ops before our after cutoff\n\t\t\tif (after && op.timestamp <= after) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// don't apply future ops\n\t\t\tif (compareTimestampSchemaVersions(op.timestamp, now) > 0) {\n\t\t\t\tfutureSeen = op.timestamp;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// we don't actually delete the view when a delete op\n\t\t\t// comes in. the view remains useful for calculating\n\t\t\t// undo operations.\n\t\t\tif (op.data.op === 'delete') {\n\t\t\t\tdeleted = true;\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tbase = applyPatch(base, op.data);\n\t\t\t\t\tif (op.data.op === 'initialize') {\n\t\t\t\t\t\tdeleted = false;\n\t\t\t\t\t\tif (op.authz) {\n\t\t\t\t\t\t\tauthz = op.authz;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t'critical',\n\t\t\t\t\t\t`Failed to apply operation to entity ${this.oid}: ${JSON.stringify(\n\t\t\t\t\t\t\top,\n\t\t\t\t\t\t)}`,\n\t\t\t\t\t\terr,\n\t\t\t\t\t);\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// track the latest timestamp\n\t\t\tif (!latestTimestamp || op.timestamp > latestTimestamp) {\n\t\t\t\tlatestTimestamp = op.timestamp;\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tview: base,\n\t\t\tlatestTimestamp: latestTimestamp ?? null,\n\t\t\tdeleted,\n\t\t\tfutureSeen,\n\t\t\tauthz,\n\t\t};\n\t};\n}\n\n/**\n * Represents the metadata for a group of entities underneath a Document.\n * Metadata is separated out this way so that these classes can be\n * garbage collected when the root Document goes out of scope.\n */\nexport class EntityFamilyMetadata {\n\tprivate ctx;\n\tprivate entities: Map<ObjectIdentifier, EntityMetadata> = new Map();\n\tprivate onPendingOperations;\n\tprivate rootOid: ObjectIdentifier;\n\n\tconstructor({\n\t\tctx,\n\t\tonPendingOperations,\n\t\trootOid,\n\t}: {\n\t\tctx: Context;\n\t\tonPendingOperations: (ops: Operation[]) => void;\n\t\trootOid: ObjectIdentifier;\n\t}) {\n\t\tthis.ctx = ctx;\n\t\tthis.rootOid = rootOid;\n\t\tthis.onPendingOperations = onPendingOperations;\n\t}\n\n\tget = (oid: ObjectIdentifier) => {\n\t\tassert(oid, 'oid is required');\n\t\tif (!this.entities.has(oid)) {\n\t\t\tthis.entities.set(oid, new EntityMetadata({ oid, ctx: this.ctx }));\n\t\t}\n\t\treturn this.entities.get(oid)!;\n\t};\n\n\tgetAllOids = () => {\n\t\treturn Array.from(this.entities.keys());\n\t};\n\n\taddConfirmedData = ({\n\t\tbaselines = [],\n\t\toperations = {},\n\t\tisLocal = false,\n\t}: {\n\t\tbaselines?: DocumentBaseline[];\n\t\toperations?: Record<ObjectIdentifier, Operation[]>;\n\t\tisLocal?: boolean;\n\t}) => {\n\t\tconst changes: Record<ObjectIdentifier, EntityChange> = {};\n\t\tfor (const baseline of baselines) {\n\t\t\tif (!areOidsRelated(this.rootOid, baseline.oid)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid baseline for entity ${this.rootOid}: ` +\n\t\t\t\t\t\tJSON.stringify(baseline),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.get(baseline.oid).addBaseline(baseline);\n\t\t\tchanges[baseline.oid] ??= { oid: baseline.oid, isLocal };\n\t\t}\n\t\tfor (const [oid, ops] of Object.entries(operations)) {\n\t\t\tif (!areOidsRelated(this.rootOid, oid)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid operations for entity ${this.rootOid}: ` +\n\t\t\t\t\t\tJSON.stringify(ops),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst added = this.get(oid).addConfirmedOperations(ops);\n\t\t\tif (added !== 0) {\n\t\t\t\tchanges[oid] ??= { oid, isLocal };\n\t\t\t}\n\t\t}\n\t\treturn Object.values(changes);\n\t};\n\n\t/**\n\t * Adds local, unconfirmed operations to the system.\n\t * The API is different here to streamline for the way\n\t * local changes are usually handled, as a list.\n\t */\n\taddPendingData = (operations: Operation[]) => {\n\t\t// when pending data is applied, we go ahead and\n\t\t// write all ephemeral changes first.\n\t\tthis.flushAllEphemeral();\n\n\t\tconst changes: Record<ObjectIdentifier, EntityChange> = {};\n\t\tfor (const op of operations) {\n\t\t\tthis.get(op.oid).addPendingOperation(op);\n\t\t\tchanges[op.oid] ??= { oid: op.oid, isLocal: true };\n\t\t}\n\t\tthis.onPendingOperations(operations);\n\t\treturn Object.values(changes);\n\t};\n\n\tprivate ephemeralMemo = new Array<Operation>();\n\tprivate flushAllEphemeral = () => {\n\t\tfor (const ent of this.entities.values()) {\n\t\t\tconst ops = ent.clearEphemeralOperations();\n\t\t\tif (ops) {\n\t\t\t\tthis.ephemeralMemo.push(...ops);\n\t\t\t}\n\t\t}\n\t\tif (this.ephemeralMemo.length) {\n\t\t\tconst ephemeralCopy = this.ephemeralMemo.slice();\n\t\t\t// must clear this first to avoid infinite recursion\n\t\t\tthis.ephemeralMemo.length = 0;\n\t\t\tthis.addPendingData(ephemeralCopy);\n\t\t}\n\t};\n\n\taddEphemeralData = (operations: Operation[]) => {\n\t\tconst changes: Record<ObjectIdentifier, EntityChange> = {};\n\t\tfor (const op of operations) {\n\t\t\tthis.get(op.oid).addEphemeralOperation(op);\n\t\t\tchanges[op.oid] ??= { oid: op.oid, isLocal: true };\n\t\t}\n\t\treturn Object.values(changes);\n\t};\n\n\treplaceAllData = ({\n\t\toperations = {},\n\t\tbaselines = [],\n\t}: {\n\t\toperations?: Record<ObjectIdentifier, Operation[]>;\n\t\tbaselines?: DocumentBaseline[];\n\t}) => {\n\t\tconst oids = Array.from(this.entities.keys());\n\t\tthis.entities.clear();\n\t\tconst changes: Record<ObjectIdentifier, EntityChange> = {};\n\t\t// changes apply to all the entities we removed things from, too\n\t\tfor (const oid of oids) {\n\t\t\tchanges[oid] = { oid, isLocal: false };\n\t\t}\n\t\tfor (const baseline of baselines) {\n\t\t\tif (!areOidsRelated(this.rootOid, baseline.oid)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid baseline for entity ${this.rootOid}: ` +\n\t\t\t\t\t\tJSON.stringify(baseline),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.get(baseline.oid).addBaseline(baseline);\n\t\t\tchanges[baseline.oid] ??= { oid: baseline.oid, isLocal: false };\n\t\t}\n\t\tfor (const [oid, ops] of Object.entries(operations)) {\n\t\t\tif (!areOidsRelated(this.rootOid, oid)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid operations for entity ${this.rootOid}: ` +\n\t\t\t\t\t\tJSON.stringify(ops),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.get(oid).addConfirmedOperations(ops);\n\t\t\tchanges[oid] ??= { oid, isLocal: false };\n\t\t}\n\t\treturn Object.values(changes);\n\t};\n\n\tdiscardPendingOperation = (operation: Operation) => {\n\t\tconst ent = this.entities.get(operation.oid);\n\t\tent?.discardPendingOperation(operation);\n\t};\n}\n", "import {\n\tBatcher,\n\tObjectIdentifier,\n\tOperation,\n\tPropertyName,\n\tgenerateId,\n\tgetOidRoot,\n\tgetUndoOperations,\n\tgroupPatchesByOid,\n\tisSuperseded,\n\toperationSupersedes,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { Entity } from './Entity.js';\nimport type { EntityStore } from './EntityStore.js';\n\nconst DEFAULT_BATCH_KEY = '@@default';\n\nexport interface OperationBatch {\n\trun: (fn: () => void) => this;\n\t/** @deprecated - use commit() */\n\tflush: () => Promise<void>;\n\tcommit: () => Promise<void>;\n\tdiscard: () => void;\n}\n\nexport class OperationBatcher {\n\tprivate batcher;\n\tprivate currentBatchKey = DEFAULT_BATCH_KEY;\n\tprivate defaultBatchTimeout: number;\n\tprivate ctx;\n\tprivate entities;\n\n\tconstructor({\n\t\tbatchTimeout = 200,\n\t\tctx,\n\t\tentities,\n\t}: {\n\t\tbatchTimeout?: number;\n\t\tctx: Context;\n\t\tentities: EntityStore;\n\t}) {\n\t\tthis.ctx = ctx;\n\t\tthis.entities = entities;\n\t\tthis.defaultBatchTimeout = batchTimeout;\n\t\tthis.batcher = new Batcher<Operation, { undoable?: boolean }>(\n\t\t\tthis.flushOperations,\n\t\t);\n\t\tthis.batcher.add({\n\t\t\tkey: DEFAULT_BATCH_KEY,\n\t\t\titems: [],\n\t\t\tmax: 100,\n\t\t\ttimeout: batchTimeout,\n\t\t\tuserData: { undoable: true },\n\t\t});\n\t}\n\n\tget isDefaultBatch() {\n\t\treturn this.currentBatchKey === DEFAULT_BATCH_KEY;\n\t}\n\n\tprivate flushOperations = async (\n\t\toperations: Operation[],\n\t\tbatchKey: string,\n\t\tmeta: { undoable?: boolean },\n\t) => {\n\t\tif (!operations.length) return;\n\t\tthis.ctx.log(\n\t\t\t'debug',\n\t\t\t'Flushing',\n\t\t\toperations.length,\n\t\t\t'operations from batch',\n\t\t\tbatchKey,\n\t\t\t'to storage / sync',\n\t\t);\n\n\t\t// next block of logic computes superseding rules to eliminate\n\t\t// operations which are 'overshadowed' by later ones on the same\n\t\t// key.\n\n\t\tconst committed: Operation[] = [];\n\t\tconst supersessions: Record<\n\t\t\tObjectIdentifier,\n\t\t\tSet<boolean | PropertyName>\n\t\t> = {};\n\t\tfor (let i = operations.length - 1; i >= 0; i--) {\n\t\t\tconst op = operations[i];\n\n\t\t\t// check for supersession from later operation which either\n\t\t\t// covers the whole id (true) or this key\n\t\t\tconst existingSupersession = supersessions[op.oid];\n\t\t\tif (existingSupersession && isSuperseded(op, existingSupersession)) {\n\t\t\t\tthis.entities.discardPendingOperation(op);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// determine if this operation supersedes others\n\t\t\tconst supersession = operationSupersedes(op);\n\t\t\tif (supersession !== false) {\n\t\t\t\tif (!supersessions[op.oid]) {\n\t\t\t\t\tsupersessions[op.oid] = new Set<boolean | PropertyName>();\n\t\t\t\t}\n\t\t\t\tsupersessions[op.oid]!.add(supersession);\n\t\t\t}\n\n\t\t\t// add this operation to final list\n\t\t\tcommitted.unshift(op);\n\t\t}\n\n\t\t// rewrite timestamps of all operations to now - this preserves\n\t\t// the linear history of operations which are sent to the server.\n\t\t// even if multiple batches are spun up in parallel and flushed\n\t\t// after delay, the final operations in each one should reflect\n\t\t// when the batch flushed, not when the changes were made.\n\t\t// This also corresponds to user-observed behavior, since unconfirmed\n\t\t// operations are applied universally after confirmed operations locally,\n\t\t// so even operations which were made before a remote operation but\n\t\t// have not been confirmed yet will appear to come after the remote one\n\t\t// despite the provisional timestamp being earlier\n\t\t// NOTE: this MUST be mutating the original operation object! this timestamp\n\t\t// also serves as a unique ID for deduplication later.\n\n\t\t// NOTE: need to rewind back in order to set timestamps correctly.\n\t\t// cannot be done in reversed loop above or timestamps would be\n\t\t// in reverse order.\n\t\tfor (const op of committed) {\n\t\t\top.timestamp = this.ctx.time.now;\n\t\t}\n\t\tawait this.commitOperations(committed, meta);\n\t};\n\n\t/**\n\t * Immediately flushes operations to storage / sync.\n\t * Providing source to second arg skips hydrating related\n\t * Entity from storage, which is useful when that Entity\n\t * isn't in storage (i.e. still creating) or just to speed\n\t * up the commit.\n\t */\n\tcommitOperations = async (\n\t\toperations: Operation[],\n\t\tmeta: { undoable?: boolean; source?: Entity },\n\t) => {\n\t\tif (!operations.length) return;\n\t\t// now is the time to decide on what the undo operations will\n\t\t// look like, based on the confirmed view of the related entities.\n\t\tif (meta.undoable) {\n\t\t\tconst undo = await this.createUndo({\n\t\t\t\tops: operations,\n\t\t\t\tsource: meta.source,\n\t\t\t});\n\t\t\tif (undo) this.ctx.undoHistory.addUndo(undo);\n\t\t}\n\t\t// ship it out to EntityStore to compute final snapshots\n\t\t// write to storage and refresh entities and queries\n\t\tawait this.entities.addData({\n\t\t\toperations,\n\t\t\tbaselines: [],\n\t\t\tisLocal: true,\n\t\t});\n\t};\n\n\t/**\n\t * Adds operations to the active batch.\n\t */\n\taddOperations = (operations: Operation[]) => {\n\t\tif (!operations.length) return;\n\t\tthis.batcher.add({\n\t\t\tkey: this.currentBatchKey,\n\t\t\titems: operations,\n\t\t});\n\t\tthis.ctx.log(\n\t\t\t`debug`,\n\t\t\t'added',\n\t\t\toperations.length,\n\t\t\t'ops to batch',\n\t\t\tthis.currentBatchKey,\n\t\t\t', size = ',\n\t\t\tthis.batcher.getSize(this.currentBatchKey),\n\t\t);\n\t};\n\n\tbatch = ({\n\t\tundoable = true,\n\t\tbatchName = generateId(),\n\t\tmax = null,\n\t\ttimeout = this.defaultBatchTimeout,\n\t}: {\n\t\t/** Allows turning off undo for this batch, making it 'permanent' */\n\t\tundoable?: boolean;\n\t\t/**\n\t\t * Provide a stable name to any invocation of .batch() and the changes made\n\t\t * within run() will all be added to the same batch. If a batch hits the max\n\t\t * limit or timeout and is flushed, the name will be reused for a new batch\n\t\t * automatically. Provide a stable name to make changes from anywhere in your\n\t\t * app to be grouped together in the same batch with the same limit behavior.\n\t\t *\n\t\t * Limit configuration provided to each invocation of .batch() with the same\n\t\t * name will overwrite any other invocation's limit configuration. It's\n\t\t * recommended to provide limits in one place and only provide a name\n\t\t * in others.\n\t\t */\n\t\tbatchName?: string;\n\t\t/**\n\t\t * The maximum number of operations the batch will hold before flushing\n\t\t * automatically. If null, the batch will not flush automatically based\n\t\t * on operation count.\n\t\t */\n\t\tmax?: number | null;\n\t\t/**\n\t\t * The number of milliseconds to wait before flushing the batch automatically.\n\t\t * If null, the batch will not flush automatically based on time. It is not\n\t\t * recommended to set this to null, as an unflushed batch will never be written\n\t\t * to storage or sync. If you do require undefined timing in a batch, make sure\n\t\t * to always call .commit() on the batch yourself.\n\t\t */\n\t\ttimeout?: number | null;\n\t} = {}): OperationBatch => {\n\t\tconst internalBatch = this.batcher.add({\n\t\t\tkey: batchName,\n\t\t\tmax,\n\t\t\ttimeout,\n\t\t\titems: [],\n\t\t\tuserData: { undoable },\n\t\t});\n\t\tconst externalApi = {\n\t\t\trun: (fn: () => void) => {\n\t\t\t\t// while the provided function runs, operations are forwarded\n\t\t\t\t// to the new batch instead of default. this relies on the function\n\t\t\t\t// being synchronous.\n\t\t\t\tthis.currentBatchKey = batchName;\n\t\t\t\tfn();\n\t\t\t\tthis.currentBatchKey = DEFAULT_BATCH_KEY;\n\t\t\t\treturn externalApi;\n\t\t\t},\n\t\t\tcommit: async () => {\n\t\t\t\t// before running a batch, the default operations must be flushed\n\t\t\t\t// this better preserves undo history behavior...\n\t\t\t\t// if we left the default batch open while flushing a named batch,\n\t\t\t\t// then the default batch would be flushed after the named batch,\n\t\t\t\t// and the default batch could contain operations both prior and\n\t\t\t\t// after the named batch. this would result in a confusing undo\n\t\t\t\t// history where the first undo might reverse changes before and\n\t\t\t\t// after a set of other changes.\n\t\t\t\tawait this.batcher.flush(DEFAULT_BATCH_KEY);\n\t\t\t\treturn internalBatch.flush();\n\t\t\t},\n\t\t\tflush: () => externalApi.commit(),\n\t\t\tdiscard: () => {\n\t\t\t\tthis.batcher.discard(batchName);\n\t\t\t},\n\t\t};\n\t\treturn externalApi;\n\t};\n\n\tflushAll = () => {\n\t\tthis.ctx.log('debug', 'Flushing all operations');\n\t\treturn Promise.all(this.batcher.flushAll());\n\t};\n\n\tprivate createUndo = async (data: {\n\t\tops: Operation[];\n\t\tsource?: Entity;\n\t\tisRedo?: boolean;\n\t}) => {\n\t\t// this can't be done on-demand because we rely on the current\n\t\t// state of the entities to calculate the inverse operations.\n\t\tconst inverseOps = await this.getInverseOperations(data);\n\n\t\tif (!inverseOps.length) return null;\n\n\t\treturn async () => {\n\t\t\tconst redo = await this.createUndo({\n\t\t\t\tops: inverseOps,\n\t\t\t\tsource: data.source,\n\t\t\t\tisRedo: true,\n\t\t\t});\n\t\t\t// set time to now for all undo operations, they're happening now.\n\t\t\tfor (const op of inverseOps) {\n\t\t\t\top.timestamp = this.ctx.time.now;\n\t\t\t}\n\n\t\t\tthis.ctx.log(\n\t\t\t\t'debug',\n\t\t\t\tdata.isRedo ? 'Redo' : 'Undo',\n\t\t\t\tinverseOps,\n\t\t\t\t'\\n was \\n',\n\t\t\t\tdata.ops,\n\t\t\t);\n\n\t\t\tawait this.commitOperations(\n\t\t\t\tinverseOps,\n\t\t\t\t// undos should not generate their own undo operations\n\t\t\t\t// since they already calculate redo as the inverse.\n\t\t\t\t{ undoable: false },\n\t\t\t);\n\t\t\treturn redo;\n\t\t};\n\t};\n\tprivate getInverseOperations = async ({\n\t\tops,\n\t\tsource,\n\t}: {\n\t\tops: Operation[];\n\t\tsource?: Entity;\n\t}) => {\n\t\tconst grouped = groupPatchesByOid(ops);\n\t\tconst inverseOps: Operation[] = [];\n\t\tconst getNow = () => this.ctx.time.now;\n\t\tawait Promise.all(\n\t\t\tObject.entries(grouped).map(async ([oid, patches]): Promise<void> => {\n\t\t\t\tconst entity = source ?? (await this.entities.hydrate(getOidRoot(oid)));\n\t\t\t\t// TODO: this is getting the rebased baseline? how? are ops being submitted early?\n\t\t\t\tconst viewData = entity?.__getViewData__(oid, 'confirmed');\n\t\t\t\tif (!viewData) {\n\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t'warn',\n\t\t\t\t\t\t'could not find entity',\n\t\t\t\t\t\toid,\n\t\t\t\t\t\t'for undo operation',\n\t\t\t\t\t\tops,\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst inverse = getUndoOperations(oid, viewData.view, patches, getNow);\n\t\t\t\tinverseOps.unshift(...inverse);\n\t\t\t}),\n\t\t);\n\t\treturn inverseOps;\n\t};\n}\n", "import { FileData } from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { Entity } from '../entities/Entity.js';\nimport { Disposable } from '../internal.js';\nimport { Sync } from '../sync/Sync.js';\nimport { EntityFile, MARK_FAILED, UPDATE } from './EntityFile.js';\n\nexport class FileManager extends Disposable {\n\tprivate sync;\n\tprivate context;\n\n\tprivate cache = new Map<string, EntityFile>();\n\n\tconstructor({ sync, context }: { sync: Sync; context: Context }) {\n\t\tsuper();\n\t\tthis.sync = sync;\n\t\tthis.context = context;\n\t\tthis.addDispose(\n\t\t\tthis.context.internalEvents.subscribe(\n\t\t\t\t'fileUploaded',\n\t\t\t\tthis.onFileUploaded,\n\t\t\t),\n\t\t);\n\t}\n\n\tadd = async (file: FileData, parent: Entity) => {\n\t\t// immediately cache the file\n\t\tlet entityFile = this.cache.get(file.id);\n\t\tif (!entityFile) {\n\t\t\tentityFile = new EntityFile(file.id, { ctx: this.context, parent });\n\t\t\tthis.cache.set(file.id, entityFile);\n\t\t}\n\n\t\tif (!file.remote) {\n\t\t\t// immediately update local files.\n\t\t\tentityFile[UPDATE](file);\n\t\t}\n\t\t// this will download any original remote file and trigger a re-upload to the\n\t\t// new file's identity, in addition to storing it on disk\n\t\tconst processedFile = await (\n\t\t\tawait this.context.files\n\t\t).add(file, { cloneRemote: true });\n\t\tentityFile[UPDATE](processedFile);\n\t};\n\n\t/**\n\t * Immediately returns an EntityFile to use, then either loads\n\t * the file from cache, local database, or the server.\n\t */\n\tget = (\n\t\tid: string,\n\t\toptions: { downloadRemote?: boolean; ctx: Context; parent: Entity },\n\t) => {\n\t\tif (this.cache.has(id)) {\n\t\t\treturn this.cache.get(id)!;\n\t\t}\n\t\tconst file = new EntityFile(id, options);\n\t\tthis.cache.set(id, file);\n\t\tthis.load(file);\n\t\treturn file;\n\t};\n\n\tprivate load = async (file: EntityFile) => {\n\t\tconst fileData = await (await this.context.files).get(file.id);\n\t\t// immediately apply any file data we have\n\t\tif (fileData) {\n\t\t\tfile[UPDATE](fileData);\n\t\t}\n\n\t\tif (!fileData?.url && (!fileData || fileData.remote)) {\n\t\t\t// maybe we don't have it yet, it might be on the server still.\n\t\t\ttry {\n\t\t\t\t// if not online, enqueue this for whenever we go online.\n\t\t\t\tif (this.sync.status !== 'active') {\n\t\t\t\t\tthis.context.log(\n\t\t\t\t\t\t'info',\n\t\t\t\t\t\t'Sync is not active, waiting for online to load file',\n\t\t\t\t\t\tfile.id,\n\t\t\t\t\t\tfile.name,\n\t\t\t\t\t);\n\t\t\t\t\tconst unsub = this.sync.subscribe('onlineChange', (online) => {\n\t\t\t\t\t\tif (online) {\n\t\t\t\t\t\t\tunsub();\n\t\t\t\t\t\t\tthis.load(file);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst result = await this.sync.getFile(file.id);\n\t\t\t\tif (result.success) {\n\t\t\t\t\t// avoid overwriting local values except for url\n\t\t\t\t\tconst copyWithUrl: FileData = {\n\t\t\t\t\t\t...result.data,\n\t\t\t\t\t\t...fileData,\n\t\t\t\t\t\turl: result.data.url,\n\t\t\t\t\t};\n\t\t\t\t\tawait (await this.context.files).update(copyWithUrl);\n\t\t\t\t\tfile[UPDATE](result.data);\n\t\t\t\t} else {\n\t\t\t\t\tthis.context.log('error', 'Failed to load file', result);\n\t\t\t\t\tif (!fileData) {\n\t\t\t\t\t\t// only mark failed if we have no local data to fall back to\n\t\t\t\t\t\tfile[MARK_FAILED](result.error?.toString());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tthis.context.log('error', 'Failed to load file', err);\n\t\t\t\tif (!fileData) {\n\t\t\t\t\t// only mark failed if we have no local data to fall back to\n\t\t\t\t\tfile[MARK_FAILED](err instanceof Error ? err.message : String(err));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate onFileUploaded = async (data: FileData) => {\n\t\tthis.context.log('debug', 'Marking file as uploaded', data.id);\n\t\t(await this.context.files).onUploaded(data.id);\n\t};\n}\n", "import { CollectionIndexFilter, hashObject } from '@verdant-web/common';\nimport { Entity } from '../entities/Entity.js';\n\nfunction existsFilter<T>(x: T | null): x is T {\n\treturn x !== null;\n}\n\nexport function filterResultSet(results: any): any {\n\tif (Array.isArray(results)) {\n\t\treturn results.map(filterResultSet).filter(existsFilter);\n\t} else if (results instanceof Entity) {\n\t\treturn results.deleted ? null : results;\n\t} else {\n\t\treturn results;\n\t}\n}\n\nexport function areIndexesEqual(\n\ta?: CollectionIndexFilter,\n\tb?: CollectionIndexFilter,\n) {\n\treturn (!a && !b) || (a && b && hashObject(a) === hashObject(b));\n}\n", "import { EventSubscriber } from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { Entity } from '../entities/Entity.js';\nimport { Disposable } from '../utils/Disposable.js';\nimport { filterResultSet } from './utils.js';\n\nexport type BaseQueryEvents = {\n\tchange: (value: any) => void;\n\tstatusChange: (status: QueryStatus) => void;\n};\n\nexport type BaseQueryOptions<T> = {\n\tcontext: Context;\n\tinitial: T;\n\tcollection: string;\n\tkey: string;\n\tshouldUpdate?: (updatedCollections: string[]) => boolean;\n};\n\nexport type QueryStatus = 'initial' | 'initializing' | 'revalidating' | 'ready';\n\nexport const ON_ALL_UNSUBSCRIBED = Symbol('ON_ALL_UNSUBSCRIBED');\nexport const UPDATE = Symbol('UPDATE');\n\n// export interface BaseQuery<T> {\n// \tsubscribe(event: 'change', callback: (value: T) => void): () => void;\n// \tsubscribe(event: 'statusChange', callback: (status: QueryStatus) => void): () => void;\n// \tsubscribe(callback: (value: T) => void): () => void;\n// }\n\nexport abstract class BaseQuery<T> extends Disposable {\n\tprivate _rawValue;\n\tprivate _value;\n\n\tprivate _events;\n\tprivate _internalUnsubscribes: (() => void)[] = [];\n\tprivate _allUnsubscribedHandler?: (query: BaseQuery<T>) => void;\n\tprivate _status: QueryStatus = 'initial';\n\tprivate _executionPromise: Promise<T> | null = null;\n\n\tprotected context;\n\n\treadonly collection;\n\treadonly key;\n\treadonly isListQuery;\n\n\tconstructor({\n\t\tinitial,\n\t\tcontext,\n\t\tcollection,\n\t\tkey,\n\t\tshouldUpdate,\n\t}: BaseQueryOptions<T>) {\n\t\tsuper();\n\t\tthis._rawValue = initial;\n\t\tthis._value = initial;\n\t\tthis.isListQuery = Array.isArray(initial);\n\t\tthis._events = new EventSubscriber<BaseQueryEvents>(\n\t\t\t(event: keyof BaseQueryEvents) => {\n\t\t\t\tif (event === 'change') {\n\t\t\t\t\tthis._allUnsubscribedHandler?.(this);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t\tthis.context = context;\n\t\tthis.key = key;\n\t\tthis.collection = collection;\n\t\tconst shouldUpdateFn =\n\t\t\tshouldUpdate ||\n\t\t\t((collections: string[]) => collections.includes(collection));\n\t\tthis.addDispose(\n\t\t\tthis.context.entityEvents.subscribe(\n\t\t\t\t'collectionsChanged',\n\t\t\t\t(collections) => {\n\t\t\t\t\tif (shouldUpdateFn(collections)) {\n\t\t\t\t\t\tthis.context.log('info', 'Updating query', this.key);\n\t\t\t\t\t\t// immediately refilter the result set - deleted\n\t\t\t\t\t\t// entities will already be nulled out\n\t\t\t\t\t\t// this.refreshValue();\n\t\t\t\t\t\tthis.execute();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t);\n\t\t// TODO: subscribe to document changes and update if necessary.\n\t}\n\n\tget current() {\n\t\treturn this._value;\n\t}\n\n\tget resolved() {\n\t\tif (this.status === 'ready') return Promise.resolve(this._value);\n\t\treturn this._executionPromise ?? this.execute();\n\t}\n\n\tget subscribed() {\n\t\treturn this._events.totalSubscriberCount() > 0;\n\t}\n\n\tget status() {\n\t\treturn this._status;\n\t}\n\n\tprivate set status(v: QueryStatus) {\n\t\tif (this._status === v) return;\n\t\tthis._status = v;\n\t\tthis._events.emit('statusChange', this._status);\n\t}\n\n\tget hasDeleted() {\n\t\tif (this.isListQuery) {\n\t\t\treturn (this._rawValue as any[]).length !== (this._value as any[]).length;\n\t\t}\n\t\treturn !!this._rawValue && !this._value;\n\t}\n\n\t/**\n\t * Subscribe to changes in the query value.\n\t *\n\t * @deprecated use the two parameter form instead\n\t */\n\tsubscribe(callback: (value: T) => void): () => void;\n\t/**\n\t * Subscribe to changes in the query value.\n\t */\n\tsubscribe(event: 'change', callback: (value: T) => void): () => void;\n\t/**\n\t * Subscribe to changes in the query state.\n\t */\n\tsubscribe(\n\t\tevent: 'statusChange',\n\t\tcallback: (status: QueryStatus) => void,\n\t): () => void;\n\tsubscribe(eventOrCallback: any, callback?: any) {\n\t\t// change subscription has special behavior...\n\t\tif (callback === undefined && typeof eventOrCallback === 'function') {\n\t\t\t// accessing for side effects... eh\n\t\t\tthis.resolved;\n\t\t\treturn this._events.subscribe('change', eventOrCallback);\n\t\t} else if (eventOrCallback === 'change' && callback !== undefined) {\n\t\t\t// accessing for side effects... eh\n\t\t\tthis.resolved;\n\t\t\treturn this._events.subscribe('change', callback);\n\t\t} else if (\n\t\t\teventOrCallback === 'statusChange' &&\n\t\t\ttypeof callback === 'function'\n\t\t) {\n\t\t\treturn this._events.subscribe(eventOrCallback, callback);\n\t\t} else {\n\t\t\tthrow new Error('Invalid invocation of Query.subscribe');\n\t\t}\n\t}\n\n\tprotected setValue = (value: T) => {\n\t\tthis._rawValue = value;\n\t\tthis.subscribeToDeleteAndRestore(this._rawValue);\n\t\tconst filtered = filterResultSet(value);\n\n\t\t// prevent excess change notifications by diffing\n\t\t// value by identity for single-value queries,\n\t\t// and by item identity for multi-value\n\t\tlet changed = true;\n\t\t// always fire change when going from initial to ready\n\t\tif (this.status === 'initializing' || this.status === 'initial') {\n\t\t\tchanged = true;\n\t\t} else {\n\t\t\t// compare values by identity, after filtering.\n\t\t\tif (this.isListQuery) {\n\t\t\t\tif (\n\t\t\t\t\t(this._value as any[]).length === (filtered as any[]).length &&\n\t\t\t\t\t(this._value as any[]).every((v, i) => v === (filtered as any[])[i])\n\t\t\t\t) {\n\t\t\t\t\tchanged = false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (this._value === filtered) {\n\t\t\t\t\tchanged = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis._value = filtered;\n\n\t\tif (changed) {\n\t\t\tthis.context.log('debug', 'Query value changed', this.key);\n\t\t\tthis._events.emit('change', this._value);\n\t\t}\n\t\tthis.status = 'ready';\n\t};\n\n\t// re-applies filtering if results have changed\n\tprotected refreshValue = () => {\n\t\tthis.setValue(this._rawValue);\n\t};\n\n\tprivate subscribeToDeleteAndRestore = (value: T) => {\n\t\twhile (this._internalUnsubscribes.length) {\n\t\t\tthis._internalUnsubscribes.pop()?.();\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tvalue.forEach((entity: any) => {\n\t\t\t\tif (entity instanceof Entity) {\n\t\t\t\t\tthis._internalUnsubscribes.push(\n\t\t\t\t\t\tentity.subscribe('delete', this.refreshValue),\n\t\t\t\t\t);\n\t\t\t\t\tthis._internalUnsubscribes.push(\n\t\t\t\t\t\tentity.subscribe('restore', this.refreshValue),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t} else if (value instanceof Entity) {\n\t\t\tthis._internalUnsubscribes.push(\n\t\t\t\tvalue.subscribe('delete', this.refreshValue),\n\t\t\t);\n\t\t\tthis._internalUnsubscribes.push(\n\t\t\t\tvalue.subscribe('restore', () => {\n\t\t\t\t\tthis.refreshValue();\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t};\n\n\texecute = () => {\n\t\tconst startTime = new Date();\n\t\tthis.context.log(\n\t\t\t'debug',\n\t\t\t`[${startTime.toLocaleTimeString()}]`,\n\t\t\t'Executing query',\n\t\t\tthis.key,\n\t\t);\n\n\t\tif (this.status === 'initial') {\n\t\t\tthis.status = 'initializing';\n\t\t} else if (this.status === 'ready') {\n\t\t\tthis.status = 'revalidating';\n\t\t}\n\t\t// no status change needed if already in a 'running' status.\n\n\t\tthis._executionPromise = this.run()\n\t\t\t.then(() => this._value)\n\t\t\t.catch((err) => {\n\t\t\t\tif (err instanceof Error) {\n\t\t\t\t\tif (\n\t\t\t\t\t\terr.name === 'InvalidStateError' ||\n\t\t\t\t\t\terr.name === 'InvalidAccessError'\n\t\t\t\t\t) {\n\t\t\t\t\t\t// possibly accessing db while it's closed. not much we can do.\n\t\t\t\t\t\treturn this._value;\n\t\t\t\t\t}\n\t\t\t\t\tthrow err;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error('Unknown error executing query');\n\t\t\t\t}\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tconst endTime = new Date();\n\t\t\t\tconst duration = endTime.getTime() - startTime.getTime();\n\t\t\t\tthis.context.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t`[${endTime.toLocaleTimeString()}]`,\n\t\t\t\t\t'Query executed',\n\t\t\t\t\tthis.key,\n\t\t\t\t\t`Duration: ${duration}ms`,\n\t\t\t\t);\n\t\t\t});\n\t\treturn this._executionPromise;\n\t};\n\tprotected abstract run(): Promise<void>;\n\n\t[ON_ALL_UNSUBSCRIBED] = (handler: (query: BaseQuery<T>) => void) => {\n\t\tthis._allUnsubscribedHandler = handler;\n\t};\n\n\tget __rawValue() {\n\t\treturn this._rawValue;\n\t}\n}\n", "import { createOid } from '@verdant-web/common';\nimport { BaseQuery, BaseQueryOptions } from './BaseQuery.js';\n\nexport class GetQuery<T> extends BaseQuery<T | null> {\n\tprivate hydrate;\n\tprivate oid;\n\n\tconstructor({\n\t\tid,\n\t\thydrate,\n\t\t...rest\n\t}: {\n\t\tid: string;\n\t\thydrate: (oid: string) => Promise<T>;\n\t} & Omit<BaseQueryOptions<T | null>, 'initial'>) {\n\t\tsuper({\n\t\t\tinitial: null,\n\t\t\t...rest,\n\t\t});\n\t\tthis.oid = createOid(rest.collection, id);\n\t\tthis.hydrate = hydrate;\n\t}\n\n\tprotected run = async () => {\n\t\tconst value = await this.hydrate(this.oid);\n\t\tthis.setValue(value);\n\t};\n}\n", "import { CollectionFilter } from '@verdant-web/common';\nimport { BaseQuery, BaseQueryOptions, UPDATE } from './BaseQuery.js';\nimport { areIndexesEqual } from './utils.js';\n\nexport class FindOneQuery<T> extends BaseQuery<T | null> {\n\tprivate index;\n\tprivate hydrate;\n\n\tconstructor({\n\t\tindex,\n\t\thydrate,\n\t\t...rest\n\t}: {\n\t\tindex?: CollectionFilter;\n\t\thydrate: (oid: string) => Promise<T>;\n\t} & Omit<BaseQueryOptions<T | null>, 'initial'>) {\n\t\tsuper({\n\t\t\tinitial: null,\n\t\t\t...rest,\n\t\t});\n\t\tthis.index = index;\n\t\tthis.hydrate = hydrate;\n\t}\n\n\tprotected run = async () => {\n\t\tconst oid = await (\n\t\t\tawait this.context.documents\n\t\t).findOneOid({\n\t\t\tcollection: this.collection,\n\t\t\tindex: this.index,\n\t\t});\n\t\tthis.setValue(oid ? await this.hydrate(oid) : null);\n\t};\n\n\t[UPDATE] = (index: CollectionFilter | undefined) => {\n\t\tif (areIndexesEqual(this.index, index)) return;\n\t\tthis.index = index;\n\t\tthis.execute();\n\t};\n}\n", "import { CollectionFilter } from '@verdant-web/common';\nimport { BaseQuery, BaseQueryOptions, UPDATE } from './BaseQuery.js';\nimport { areIndexesEqual } from './utils.js';\n\nexport class FindPageQuery<T> extends BaseQuery<T[]> {\n\tprivate index;\n\tprivate hydrate;\n\tprivate _pageSize: number;\n\tprivate _page: number;\n\tprivate _hasNextPage: boolean = false;\n\n\tget pageSize() {\n\t\treturn this._pageSize;\n\t}\n\n\tget page() {\n\t\treturn this._page;\n\t}\n\n\tget hasNextPage() {\n\t\treturn this._hasNextPage;\n\t}\n\n\tget hasPreviousPage() {\n\t\treturn this._page > 0;\n\t}\n\n\tconstructor({\n\t\tindex,\n\t\thydrate,\n\t\tpageSize,\n\t\tpage,\n\t\t...rest\n\t}: {\n\t\tindex?: CollectionFilter;\n\t\thydrate: (oid: string) => Promise<T>;\n\t\tpageSize: number;\n\t\tpage: number;\n\t} & Omit<BaseQueryOptions<T[]>, 'initial'>) {\n\t\tsuper({\n\t\t\tinitial: [],\n\t\t\t...rest,\n\t\t});\n\t\tthis.index = index;\n\t\tthis.hydrate = hydrate;\n\t\tthis._pageSize = pageSize;\n\t\tthis._page = page;\n\t}\n\n\tprotected run = async () => {\n\t\tconst { result, hasNextPage } = await (\n\t\t\tawait this.context.documents\n\t\t).findAllOids({\n\t\t\tcollection: this.collection,\n\t\t\tindex: this.index,\n\t\t\tlimit: this._pageSize,\n\t\t\toffset: this._page * this._pageSize,\n\t\t});\n\t\tthis._hasNextPage = hasNextPage;\n\t\tthis.setValue(await Promise.all(result.map(this.hydrate)));\n\t};\n\n\tnextPage = async () => {\n\t\tif (!this.hasNextPage) return;\n\n\t\tthis._page++;\n\t\tawait this.run();\n\t};\n\n\tpreviousPage = async () => {\n\t\tif (this._page === 0) return;\n\n\t\tthis._page--;\n\t\tawait this.run();\n\t};\n\n\tsetPage = async (page: number) => {\n\t\tthis._page = page;\n\t\tawait this.run();\n\t};\n\n\t[UPDATE] = (index: CollectionFilter | undefined) => {\n\t\tif (areIndexesEqual(this.index, index)) return;\n\t\tthis.index = index;\n\t\tthis.execute();\n\t};\n}\n", "import { CollectionFilter } from '@verdant-web/common';\nimport { BaseQuery, BaseQueryOptions, UPDATE } from './BaseQuery.js';\nimport { areIndexesEqual } from './utils.js';\n\nexport class FindInfiniteQuery<T> extends BaseQuery<T[]> {\n\tprivate index;\n\tprivate hydrate;\n\tprivate _upToPage = 1;\n\tprivate _pageSize: number;\n\tprivate _hasNextPage: boolean = false;\n\n\tget pageSize() {\n\t\treturn this._pageSize;\n\t}\n\n\tget hasMore() {\n\t\treturn this._hasNextPage;\n\t}\n\n\tconstructor({\n\t\thydrate,\n\t\tpageSize,\n\t\tindex,\n\t\t...rest\n\t}: {\n\t\thydrate: (oid: string) => Promise<T>;\n\t\tpageSize: number;\n\t\tindex?: CollectionFilter;\n\t} & Omit<BaseQueryOptions<T[]>, 'initial'>) {\n\t\tsuper({\n\t\t\tinitial: [],\n\t\t\t...rest,\n\t\t});\n\t\tthis.index = index;\n\t\tthis.hydrate = hydrate;\n\t\tthis._pageSize = pageSize;\n\t}\n\n\tprotected run = async () => {\n\t\tconst { result, hasNextPage } = await (\n\t\t\tawait this.context.documents\n\t\t).findAllOids({\n\t\t\tcollection: this.collection,\n\t\t\tlimit: this._pageSize * this._upToPage,\n\t\t\toffset: 0,\n\t\t\tindex: this.index,\n\t\t});\n\t\tthis._hasNextPage = hasNextPage;\n\t\tthis.setValue(await Promise.all(result.map(this.hydrate)));\n\t};\n\n\tpublic loadMore = async () => {\n\t\tconst { result, hasNextPage } = await (\n\t\t\tawait this.context.documents\n\t\t).findAllOids({\n\t\t\tcollection: this.collection,\n\t\t\tlimit: this._pageSize,\n\t\t\toffset: this._pageSize * this._upToPage,\n\t\t\tindex: this.index,\n\t\t});\n\t\tthis._hasNextPage = hasNextPage;\n\t\tthis._upToPage++;\n\t\tthis.setValue([\n\t\t\t...this.current,\n\t\t\t...(await Promise.all(result.map(this.hydrate))),\n\t\t]);\n\t};\n\n\t[UPDATE] = (index: CollectionFilter | undefined) => {\n\t\tif (areIndexesEqual(this.index, index)) return;\n\t\tthis.index = index;\n\t\tthis.execute();\n\t};\n}\n", "import { CollectionFilter } from '@verdant-web/common';\nimport { BaseQuery, BaseQueryOptions, UPDATE } from './BaseQuery.js';\nimport { areIndexesEqual } from './utils.js';\n\nexport class FindAllQuery<T> extends BaseQuery<T[]> {\n\tprivate index;\n\tprivate hydrate;\n\n\tconstructor({\n\t\tindex,\n\t\thydrate,\n\t\t...rest\n\t}: {\n\t\tindex?: CollectionFilter;\n\t\thydrate: (oid: string) => Promise<T>;\n\t} & Omit<BaseQueryOptions<T[]>, 'initial'>) {\n\t\tsuper({\n\t\t\tinitial: [],\n\t\t\t...rest,\n\t\t});\n\t\tthis.index = index;\n\t\tthis.hydrate = hydrate;\n\t}\n\n\tprotected run = async () => {\n\t\tconst { result: oids } = await (\n\t\t\tawait this.context.documents\n\t\t).findAllOids({\n\t\t\tcollection: this.collection,\n\t\t\tindex: this.index,\n\t\t});\n\t\tthis.context.log(\n\t\t\t'debug',\n\t\t\t`FindAllQuery: ${oids.length} oids found: ${oids}`,\n\t\t);\n\t\tthis.setValue(await Promise.all(oids.map(this.hydrate)));\n\t};\n\n\t[UPDATE] = (index: CollectionFilter | undefined) => {\n\t\tif (areIndexesEqual(this.index, index)) return;\n\t\tthis.index = index;\n\t\tthis.execute();\n\t};\n}\n", "import {\n\tAuthorizationKey,\n\tCollectionFilter,\n\thashObject,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { EntityStore } from '../entities/EntityStore.js';\nimport { GetQuery } from './GetQuery.js';\nimport { QueryCache } from './QueryCache.js';\nimport { FindOneQuery } from './FindOneQuery.js';\nimport { FindPageQuery } from './FindPageQuery.js';\nimport { FindInfiniteQuery } from './FindInfiniteQuery.js';\nimport { FindAllQuery } from './FindAllQuery.js';\nimport { DocumentManager } from '../entities/DocumentManager.js';\nimport { ObjectEntity } from '../index.js';\nimport { UPDATE } from './BaseQuery.js';\n\nexport class CollectionQueries<\n\tT extends ObjectEntity<any, any>,\n\tInit,\n\tFilter extends CollectionFilter,\n> {\n\tprivate cache;\n\tprivate collection;\n\tprivate hydrate: (oid: string) => Promise<T>;\n\tprivate context;\n\tprivate documentManager;\n\n\tput: (\n\t\tinit: Init,\n\t\toptions?: { undoable?: boolean; access?: AuthorizationKey },\n\t) => Promise<T>;\n\tdelete: (id: string, options?: { undoable?: boolean }) => Promise<void>;\n\tdeleteAll: (ids: string[], options?: { undoable?: boolean }) => Promise<void>;\n\tclone: (\n\t\tentity: ObjectEntity<any, any>,\n\t\toptions?: {\n\t\t\tundoable?: boolean;\n\t\t\taccess?: AuthorizationKey;\n\t\t\tprimaryKey?: string;\n\t\t},\n\t) => Promise<T>;\n\n\tconstructor({\n\t\tcollection,\n\t\tcache,\n\t\tentities,\n\t\tcontext,\n\t\tdocumentManager,\n\t}: {\n\t\tcollection: string;\n\t\tcache: QueryCache;\n\t\tentities: EntityStore;\n\t\tcontext: Context;\n\t\tdocumentManager: DocumentManager<any>;\n\t}) {\n\t\tthis.cache = cache;\n\t\tthis.collection = collection;\n\t\tthis.hydrate = entities.hydrate as any;\n\t\tthis.context = context;\n\t\tthis.documentManager = documentManager;\n\n\t\tthis.put = this.documentManager.create.bind(\n\t\t\tthis.documentManager,\n\t\t\tthis.collection,\n\t\t);\n\t\tthis.delete = this.documentManager.delete.bind(\n\t\t\tthis.documentManager,\n\t\t\tthis.collection,\n\t\t);\n\t\tthis.deleteAll = this.documentManager.deleteAllFromCollection.bind(\n\t\t\tthis.documentManager,\n\t\t\tthis.collection,\n\t\t);\n\t\tthis.clone = this.documentManager.clone.bind(\n\t\t\tthis.documentManager,\n\t\t\tthis.collection,\n\t\t);\n\t}\n\n\tprivate serializeIndex = (index?: CollectionFilter) => {\n\t\tif (!index) return '';\n\t\treturn hashObject(index);\n\t};\n\n\tget = (id: string) => {\n\t\tconst key = `get:${this.collection}:${id}`;\n\t\treturn this.cache.getOrSet(\n\t\t\tkey,\n\t\t\t() =>\n\t\t\t\tnew GetQuery<T>({\n\t\t\t\t\tid,\n\t\t\t\t\tcollection: this.collection,\n\t\t\t\t\thydrate: this.hydrate,\n\t\t\t\t\tcontext: this.context,\n\t\t\t\t\tkey,\n\t\t\t\t}),\n\t\t);\n\t};\n\n\tfindOne = ({\n\t\tindex,\n\t\tkey: providedKey,\n\t}: { index?: Filter; key?: string } = {}) => {\n\t\tconst key =\n\t\t\tprovidedKey || `findOne:${this.collection}:${this.serializeIndex(index)}`;\n\t\treturn this.cache.getOrSet(\n\t\t\tkey,\n\t\t\t() =>\n\t\t\t\tnew FindOneQuery<T>({\n\t\t\t\t\tindex,\n\t\t\t\t\tcollection: this.collection,\n\t\t\t\t\thydrate: this.hydrate,\n\t\t\t\t\tcontext: this.context,\n\t\t\t\t\tkey,\n\t\t\t\t}),\n\t\t\t(existing) => {\n\t\t\t\texisting[UPDATE](index);\n\t\t\t},\n\t\t);\n\t};\n\n\tfindAll = ({\n\t\tindex,\n\t\tkey: providedKey,\n\t}: { index?: Filter; key?: string } = {}) => {\n\t\tconst key =\n\t\t\tprovidedKey || `findAll:${this.collection}:${this.serializeIndex(index)}`;\n\t\treturn this.cache.getOrSet(\n\t\t\tkey,\n\t\t\t() =>\n\t\t\t\tnew FindAllQuery<T>({\n\t\t\t\t\tindex,\n\t\t\t\t\tcollection: this.collection,\n\t\t\t\t\thydrate: this.hydrate,\n\t\t\t\t\tcontext: this.context,\n\t\t\t\t\tkey,\n\t\t\t\t}),\n\t\t\t(existing) => {\n\t\t\t\texisting[UPDATE](index);\n\t\t\t},\n\t\t);\n\t};\n\n\tfindPage = ({\n\t\tindex,\n\t\tpageSize,\n\t\tpage,\n\t\tkey: providedKey,\n\t}: {\n\t\tindex?: Filter;\n\t\tpageSize: number;\n\t\tpage: number;\n\t\tkey?: string;\n\t}) => {\n\t\tconst key =\n\t\t\tprovidedKey ||\n\t\t\t`findPage:${this.collection}:${this.serializeIndex(index)}:${pageSize}`;\n\t\treturn this.cache.getOrSet(\n\t\t\tkey,\n\t\t\t() =>\n\t\t\t\tnew FindPageQuery<T>({\n\t\t\t\t\tindex,\n\t\t\t\t\tcollection: this.collection,\n\t\t\t\t\thydrate: this.hydrate,\n\t\t\t\t\tcontext: this.context,\n\t\t\t\t\tkey,\n\t\t\t\t\tpageSize,\n\t\t\t\t\tpage,\n\t\t\t\t}),\n\t\t\t(existing) => {\n\t\t\t\texisting[UPDATE](index);\n\t\t\t},\n\t\t);\n\t};\n\n\tfindAllInfinite = ({\n\t\tindex,\n\t\tpageSize,\n\t\tkey: providedKey,\n\t}: {\n\t\tindex?: Filter;\n\t\tpageSize: number;\n\t\tkey?: string;\n\t}) => {\n\t\tconst key =\n\t\t\tprovidedKey ||\n\t\t\t`findAllInfinite:${this.collection}:${this.serializeIndex(\n\t\t\t\tindex,\n\t\t\t)}:${pageSize}`;\n\t\treturn this.cache.getOrSet(\n\t\t\tkey,\n\t\t\t() =>\n\t\t\t\tnew FindInfiniteQuery<T>({\n\t\t\t\t\tindex,\n\t\t\t\t\tcollection: this.collection,\n\t\t\t\t\thydrate: this.hydrate,\n\t\t\t\t\tcontext: this.context,\n\t\t\t\t\tkey,\n\t\t\t\t\tpageSize,\n\t\t\t\t}),\n\t\t\t(existing) => {\n\t\t\t\texisting[UPDATE](index);\n\t\t\t},\n\t\t);\n\t};\n}\n", "import { Context } from '../context/context.js';\nimport { Disposable } from '../utils/Disposable.js';\nimport { BaseQuery, ON_ALL_UNSUBSCRIBED } from './BaseQuery.js';\n\nexport class QueryCache extends Disposable {\n\tprivate _cache: Map<string, BaseQuery<any>> = new Map();\n\tprivate _evictionTime;\n\tprivate context;\n\t/** A set of query keys to keep alive even if they unsubscribe */\n\tprivate _holds = new Set<string>();\n\n\tconstructor({\n\t\tevictionTime = 5 * 1000,\n\t\tcontext,\n\t}: {\n\t\tevictionTime?: number;\n\t\tcontext: Context;\n\t}) {\n\t\tsuper();\n\n\t\tthis._evictionTime = evictionTime;\n\t\tthis.context = context;\n\t\tthis.addDispose(\n\t\t\tthis.context.internalEvents.subscribe(\n\t\t\t\t'persistenceReset',\n\t\t\t\tthis.forceRefreshAll,\n\t\t\t),\n\t\t);\n\t}\n\n\tget activeKeys() {\n\t\treturn Array.from(this._cache.keys());\n\t}\n\n\tget<T extends BaseQuery<any>>(key: string): T | null {\n\t\treturn (this._cache.get(key) as T) || null;\n\t}\n\n\tset<V extends BaseQuery<any>>(value: V) {\n\t\tthis._cache.set(value.key, value);\n\t\tvalue[ON_ALL_UNSUBSCRIBED](this.enqueueQueryEviction);\n\t\t// immediately enqueue a check to see if this query should be evicted --\n\t\t// this basically gives code X seconds to subscribe to the query before\n\t\t// it gets evicted.\n\t\tthis.enqueueQueryEviction(value);\n\n\t\treturn value;\n\t}\n\n\tgetOrSet<V extends BaseQuery<any>>(\n\t\tkey: string,\n\t\tcreate: () => V,\n\t\tupdate?: (query: V) => void,\n\t) {\n\t\tconst existing = this.get<V>(key);\n\t\tif (existing) {\n\t\t\tupdate?.(existing);\n\t\t\treturn existing;\n\t\t}\n\t\tthis.context.log('debug', 'QueryCache: creating new query', key);\n\t\treturn this.set(create());\n\t}\n\n\tprivate enqueueQueryEviction = (query: BaseQuery<any>) => {\n\t\tsetTimeout(() => {\n\t\t\tif (query.subscribed) return;\n\n\t\t\tif (this._holds.has(query.key)) {\n\t\t\t\tthis.context.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'QueryCache: keepAlive hold on query preserves after unsubscribe',\n\t\t\t\t\tquery.key,\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// double check before evicting... possible the cache\n\t\t\t// got a different version of this query.\n\t\t\tif (this._cache.get(query.key) === query) {\n\t\t\t\tthis._cache.delete(query.key);\n\t\t\t\tthis.context.log('debug', 'QueryCache: evicted query', query.key);\n\t\t\t}\n\t\t}, this._evictionTime);\n\t};\n\n\tdropAll = () => {\n\t\tthis.context.log(\n\t\t\t'debug',\n\t\t\t'QueryCache: drop all',\n\t\t\tthis._cache.size,\n\t\t\t'queries',\n\t\t);\n\t\tthis._cache.forEach((query) => query.dispose());\n\t\tthis._cache.clear();\n\t};\n\n\tforceRefreshAll = () => {\n\t\tthis.context.log(\n\t\t\t'debug',\n\t\t\t'QueryCache: force refresh all',\n\t\t\tthis._cache.size,\n\t\t\t'queries',\n\t\t);\n\t\tthis._cache.forEach((q) => q.execute());\n\t};\n\n\tkeepAlive(key: string) {\n\t\tthis._holds.add(key);\n\t\tthis.context.log('debug', 'QueryCache: keepAlive', key);\n\t}\n\n\tdropKeepAlive(key: string) {\n\t\tthis._holds.delete(key);\n\t\tconst cached = this.get(key);\n\t\tif (!cached) return;\n\t\tif (!cached.subscribed) {\n\t\t\tthis.context.log(\n\t\t\t\t'debug',\n\t\t\t\t'QueryCache: dropKeepAlive on unsubscribed query; queuing eviction',\n\t\t\t\tkey,\n\t\t\t);\n\t\t\tthis.enqueueQueryEviction(cached);\n\t\t}\n\t}\n\n\tget keepAlives() {\n\t\treturn this._holds;\n\t}\n}\n\nexport type PublicQueryCacheAPI = Pick<\n\tQueryCache,\n\t| 'keepAlive'\n\t| 'dropKeepAlive'\n\t| 'keepAlives'\n\t| 'forceRefreshAll'\n\t| 'activeKeys'\n>;\n", "export async function attemptToRegisterBackgroundSync() {\n\ttry {\n\t\tconst status = await navigator.permissions.query({\n\t\t\tname: 'periodic-background-sync' as any,\n\t\t});\n\t\tif (status.state === 'granted') {\n\t\t\t// Periodic background sync can be used.\n\t\t\tconst registration = await navigator.serviceWorker.ready;\n\t\t\tif ('periodicSync' in registration) {\n\t\t\t\ttry {\n\t\t\t\t\tawait (registration.periodicSync as any).register('verdant-sync', {\n\t\t\t\t\t\t// An interval of one day.\n\t\t\t\t\t\tminInterval: 24 * 60 * 60 * 1000,\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Periodic background sync cannot be used.\n\t\t\t\t\tconsole.warn('Failed to register background sync:', error);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Periodic background sync cannot be used.\n\t\t\tconsole.debug('Background sync permission is not granted:', status);\n\t\t}\n\t} catch (error) {\n\t\tconsole.error('Failed to initiate background sync:', error);\n\t}\n}\n", "import { FileData } from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { Disposable } from '../utils/Disposable.js';\nimport { ServerSyncEndpointProvider } from './ServerSyncEndpointProvider.js';\n\nexport interface FileUploadResult {\n\tsuccess: boolean;\n\terror?: string;\n}\n\nexport type FilePullResult =\n\t| {\n\t\t\tsuccess: true;\n\t\t\tdata: FileData;\n\t }\n\t| {\n\t\t\tsuccess: false;\n\t\t\terror?: any;\n\t };\n\nexport class FileSync extends Disposable {\n\tprivate endpointProvider: ServerSyncEndpointProvider;\n\tprivate ctx;\n\n\tconstructor({\n\t\tendpointProvider,\n\t\tctx,\n\t}: {\n\t\tendpointProvider: ServerSyncEndpointProvider;\n\t\tctx: Context;\n\t}) {\n\t\tsuper();\n\t\tthis.endpointProvider = endpointProvider;\n\t\tthis.ctx = ctx;\n\t\tthis.addDispose(\n\t\t\tctx.internalEvents.subscribe('fileAdded', this.onFileAdded),\n\t\t);\n\t}\n\n\tprivate onFileAdded = async (data: FileData) => {\n\t\tif (data.remote) return;\n\t\tthis.ctx.log('debug', 'Uploading file', data.id, data.name);\n\t\ttry {\n\t\t\tawait this.uploadFile(data);\n\t\t} catch (e) {\n\t\t\tthis.ctx.log('error', 'File upload failed', e);\n\t\t}\n\t};\n\n\t/**\n\t * Attempts to upload a file to the sync server. Will be retried\n\t * according to retry config.\n\t */\n\tuploadFile = async (\n\t\tdata: FileData,\n\t\tretries: { max: number; current: number } = { current: 0, max: 3 },\n\t): Promise<FileUploadResult> => {\n\t\tconst file = data.file;\n\n\t\tif (!file) {\n\t\t\tthrow new Error('Cannot upload a non-local file');\n\t\t}\n\n\t\t// multipart upload\n\t\tconst { files: fileEndpoint, token } =\n\t\t\tawait this.endpointProvider.getEndpoints();\n\n\t\tconst formData = new FormData();\n\t\tformData.append('file', file);\n\n\t\ttry {\n\t\t\tconst response = await this.ctx.environment.fetch(\n\t\t\t\tfileEndpoint + `/${data.id}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\tbody: formData,\n\t\t\t\t\tcredentials: 'include',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (response.ok) {\n\t\t\t\tthis.ctx.internalEvents.emit(`fileUploaded:${data.id}`, data);\n\t\t\t\tthis.ctx.internalEvents.emit('fileUploaded', data);\n\t\t\t\tthis.ctx.log('info', 'File upload successful');\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tconst responseText = await response.text();\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'error',\n\t\t\t\t\t'File upload failed',\n\t\t\t\t\tresponse.status,\n\t\t\t\t\tresponseText,\n\t\t\t\t);\n\t\t\t\tif (response.status < 500 || retries.current >= retries.max) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\terror: `Failed to upload file: ${response.status} ${responseText}`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 1000));\n\t\t\t\treturn this.uploadFile(data, {\n\t\t\t\t\tmax: retries.max,\n\t\t\t\t\tcurrent: retries.current + 1,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tthis.ctx.log('error', 'File upload failed', e);\n\t\t\tif (retries.current >= retries.max) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: (e as Error).message,\n\t\t\t\t};\n\t\t\t}\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 1000));\n\t\t\treturn this.uploadFile(data, {\n\t\t\t\tmax: retries.max,\n\t\t\t\tcurrent: retries.current + 1,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Pulls a file from the server by its ID. Will be retried\n\t * according to retry config.\n\t */\n\tgetFile = async (\n\t\tid: string,\n\t\tretries: { current: number; max: number } = { current: 0, max: 3 },\n\t): Promise<FilePullResult> => {\n\t\tconst { files: fileEndpoint, token } =\n\t\t\tawait this.endpointProvider.getEndpoints();\n\n\t\ttry {\n\t\t\tconst response = await this.ctx.environment.fetch(\n\t\t\t\tfileEndpoint + `/${id}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\tcredentials: 'include',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (response.ok) {\n\t\t\t\tconst data = await response.json();\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tdata,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'warn',\n\t\t\t\t\t'File information fetch failed',\n\t\t\t\t\tfileEndpoint + `/${id}`,\n\t\t\t\t\tresponse.status,\n\t\t\t\t\tawait response.text(),\n\t\t\t\t);\n\t\t\t\tif (\n\t\t\t\t\t(response.status < 500 && response.status !== 404) ||\n\t\t\t\t\tretries.current >= retries.max\n\t\t\t\t) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\terror: `Failed to fetch file: ${response.status}`,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 1000));\n\t\t\t\treturn this.getFile(id, {\n\t\t\t\t\tcurrent: retries.current + 1,\n\t\t\t\t\tmax: retries.max,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'warn',\n\t\t\t\t'File information fetch failed',\n\t\t\t\t`${fileEndpoint}/${id}`,\n\t\t\t\te,\n\t\t\t);\n\t\t\tif (retries.current >= retries.max) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: (e as Error).message,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 1000));\n\t\t\treturn this.getFile(id, {\n\t\t\t\tcurrent: retries.current + 1,\n\t\t\t\tmax: retries.max,\n\t\t\t});\n\t\t}\n\t};\n}\n", "import {\n\tBatch,\n\tBatcher,\n\tEventSubscriber,\n\tServerMessage,\n\tVerdantInternalPresence,\n\tinitialInternalPresence,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport type { UserInfo } from '../index.js';\nimport { LocalReplicaInfo } from '../persistence/interfaces.js';\n\nexport const HANDLE_MESSAGE = Symbol('handleMessage');\n\nexport class PresenceManager<\n\tProfile = any,\n\tPresence = any,\n> extends EventSubscriber<{\n\t/**\n\t * Fired when a particular peer's presence changes\n\t */\n\tpeerChanged: (userId: string, presence: UserInfo<Profile, Presence>) => void;\n\t/**\n\t * Fired immediately when a change to local presence is made. This change may not\n\t * yet have been sent to the server (see: \"update\" event)\n\t */\n\tselfChanged: (presence: UserInfo<Profile, Presence>) => void;\n\t/** Fired when any number of peer presences have changed */\n\tpeersChanged: (peers: Record<string, UserInfo<Profile, Presence>>) => void;\n\t/** Fired when a peer presence goes offline */\n\tpeerLeft: (userId: string, lastPresence: UserInfo<Profile, Presence>) => void;\n\t/** Fired after local presence changes are flushed to the server. */\n\tupdate: (data: {\n\t\tpresence?: Presence;\n\t\tinternal?: VerdantInternalPresence;\n\t}) => void;\n\tload: () => void;\n\t/** Fired on any change to a peer or the local user */\n\tchange: () => void;\n}> {\n\tprivate _peers = {} as Record<string, UserInfo<Profile, Presence>>;\n\tprivate _self = { profile: {} } as UserInfo<Profile, Presence>;\n\t// keep track of own replica IDs - applications may care if we're \"alone\" but with multiple devices.\n\tprivate _selfReplicaIds = new Set<string>();\n\tprivate _peerIds = new Array<string>();\n\tprivate _updateBatcher;\n\tprivate _updateBatch: Batch<{\n\t\tpresence?: Partial<Presence>;\n\t\tinternal?: Partial<VerdantInternalPresence>;\n\t}>;\n\n\tget self() {\n\t\treturn this._self;\n\t}\n\n\tget peers() {\n\t\treturn this._peers;\n\t}\n\n\tget peerIds() {\n\t\treturn this._peerIds;\n\t}\n\n\tget everyone() {\n\t\tconst everyone = { ...this._peers };\n\t\teveryone[this.self.id] = this.self;\n\t\treturn everyone;\n\t}\n\n\tget selfReplicaIds() {\n\t\treturn this._selfReplicaIds;\n\t}\n\n\tconstructor({\n\t\tinitialPresence,\n\t\tupdateBatchTimeout = 200,\n\t\tdefaultProfile,\n\t\tctx,\n\t}: {\n\t\tinitialPresence: Presence;\n\t\tdefaultProfile: Profile;\n\t\tupdateBatchTimeout?: number;\n\t\tctx: Context;\n\t}) {\n\t\tsuper();\n\t\tthis.self.presence = initialPresence;\n\t\tthis.self.profile = defaultProfile;\n\t\tthis.self.internal = initialInternalPresence;\n\t\tthis.self.id = '';\n\t\tthis.self.replicaId = '';\n\n\t\t// set the local replica ID as soon as it's loaded\n\t\tctx.waitForInitialization\n\t\t\t.then(() => ctx.meta)\n\t\t\t.then((meta) => meta.getLocalReplica())\n\t\t\t.then((info) => {\n\t\t\t\tthis.self.replicaId = info.id;\n\t\t\t});\n\n\t\tthis._updateBatcher = new Batcher(this.flushPresenceUpdates);\n\t\tthis._updateBatch = this._updateBatcher.add({\n\t\t\tmax: 25,\n\t\t\ttimeout: updateBatchTimeout,\n\t\t\titems: [],\n\t\t\tkey: 'default',\n\t\t});\n\t}\n\n\t/**\n\t * Decides if an update is for the local user or not. Even if it's a different replica\n\t * than the local one.\n\t *\n\t * If the replicaId matches, we use that first - we may not know the local replica's User ID yet,\n\t * e.g. on the first presence update.\n\t *\n\t * Otherwise, match the user ID to our local copy.\n\t */\n\tprivate isSelf = (\n\t\tlocalReplicaInfo: LocalReplicaInfo,\n\t\tuserInfo: UserInfo<Profile, Presence>,\n\t) => {\n\t\treturn (\n\t\t\tlocalReplicaInfo.id === userInfo.replicaId ||\n\t\t\tthis._selfReplicaIds.has(userInfo.replicaId) ||\n\t\t\tthis._self.id === userInfo.id\n\t\t);\n\t};\n\n\t[HANDLE_MESSAGE] = async (\n\t\tlocalReplicaInfo: LocalReplicaInfo,\n\t\tmessage: ServerMessage,\n\t) => {\n\t\tlet peersChanged = false;\n\t\tlet selfChanged = false;\n\t\tconst peerIdsSet = new Set<string>(this.peerIds);\n\n\t\tif (message.type === 'presence-changed') {\n\t\t\tif (this.isSelf(localReplicaInfo, message.userInfo)) {\n\t\t\t\tthis._self = message.userInfo;\n\t\t\t\tthis._selfReplicaIds.add(message.userInfo.replicaId);\n\t\t\t\tselfChanged = true;\n\t\t\t\tthis.emit('selfChanged', message.userInfo);\n\t\t\t} else {\n\t\t\t\tpeerIdsSet.add(message.userInfo.id);\n\t\t\t\tthis._peers[message.userInfo.id] = message.userInfo;\n\t\t\t\tpeersChanged = true;\n\t\t\t\tthis.emit('peerChanged', message.userInfo.id, message.userInfo);\n\t\t\t}\n\t\t} else if (message.type === 'sync-resp') {\n\t\t\t// reset to provided presence data, which includes all peers.\n\t\t\tthis._peers = {};\n\t\t\tpeerIdsSet.clear();\n\n\t\t\tfor (const [id, userInfo] of Object.entries(message.peerPresence)) {\n\t\t\t\tif (this.isSelf(localReplicaInfo, userInfo)) {\n\t\t\t\t\tthis._self = userInfo;\n\t\t\t\t\tthis._selfReplicaIds.add(userInfo.replicaId);\n\t\t\t\t\tselfChanged = true;\n\t\t\t\t\tthis.emit('selfChanged', userInfo);\n\t\t\t\t} else {\n\t\t\t\t\tpeersChanged = true;\n\t\t\t\t\tpeerIdsSet.add(id);\n\t\t\t\t\tthis._peers[id] = userInfo;\n\t\t\t\t\tthis.emit('peerChanged', id, userInfo);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (message.type === 'presence-offline') {\n\t\t\tpeerIdsSet.delete(message.userId);\n\t\t\tconst lastPresence = this._peers[message.userId];\n\t\t\tdelete this._peers[message.userId];\n\t\t\tpeersChanged = true;\n\t\t\tthis.emit('peerLeft', message.userId, lastPresence);\n\t\t}\n\t\tif (peersChanged) {\n\t\t\t// important that this stays sorted to keep stable order, don't want\n\t\t\t// peers swapping around.\n\t\t\tthis._peerIds = Array.from(peerIdsSet).sort();\n\t\t\tthis.emit('peersChanged', this._peers);\n\t\t}\n\t\tif (peersChanged || selfChanged) {\n\t\t\tthis.emit('change');\n\t\t}\n\t};\n\n\tupdate = async (presence: Partial<Presence>) => {\n\t\tthis._updateBatch.update({\n\t\t\titems: [{ presence }],\n\t\t});\n\t\t// proactively update the local presence\n\t\tthis.self.presence = { ...this.self.presence, ...presence };\n\t\tthis.emit('selfChanged', this.self);\n\t\tthis.emit('change');\n\t};\n\n\tflushPresenceUpdates = (\n\t\tpresenceUpdates: {\n\t\t\tpresence?: Partial<Presence>;\n\t\t\tinternal?: Partial<VerdantInternalPresence>;\n\t\t}[],\n\t) => {\n\t\tconst data = {\n\t\t\tpresence: this.self.presence,\n\t\t\tinternal: this.self.internal,\n\t\t};\n\t\tfor (const update of presenceUpdates) {\n\t\t\tif (update.presence) {\n\t\t\t\tObject.assign(data.presence as any, update.presence);\n\t\t\t}\n\t\t\tif (update.internal) {\n\t\t\t\tObject.assign(data.internal, update.internal);\n\t\t\t}\n\t\t}\n\t\tthis.emit('update', data);\n\t};\n\n\tsetViewId = (viewId: string | undefined) => {\n\t\tthis._updateBatch.update({\n\t\t\titems: [{ internal: { viewId } }],\n\t\t});\n\t\tthis.self.internal.viewId = viewId;\n\t\tthis.emit('selfChanged', this.self);\n\t\tthis.emit('change');\n\t};\n\n\tsetFieldId = (fieldId: string | undefined, timestamp = Date.now()) => {\n\t\tthis._updateBatch.update({\n\t\t\titems: [\n\t\t\t\t{ internal: { lastFieldId: fieldId, lastFieldTimestamp: timestamp } },\n\t\t\t],\n\t\t});\n\t\tthis.self.internal.lastFieldId = fieldId;\n\t\tthis.emit('selfChanged', this.self);\n\t\tthis.emit('change');\n\t};\n\n\t/**\n\t * Get all peers that are in the same view as the local user.\n\t */\n\tgetViewPeers = () => {\n\t\treturn (\n\t\t\tthis._peerIds\n\t\t\t\t.map((id) => this._peers[id])\n\t\t\t\t// undefined view matches all peers. otherwise,\n\t\t\t\t// filter to only those in the same view.\n\t\t\t\t.filter(\n\t\t\t\t\t(peer) =>\n\t\t\t\t\t\tthis.self.internal.viewId === undefined ||\n\t\t\t\t\t\tpeer.internal.viewId === this.self.internal.viewId,\n\t\t\t\t)\n\t\t);\n\t};\n\n\t/**\n\t * Get all peers that have interacted with the specified\n\t * field most recently.\n\t */\n\tgetFieldPeers = (fieldId: string, expirationPeriod = 60 * 1000) => {\n\t\treturn this._peerIds\n\t\t\t.map((id) => this._peers[id])\n\t\t\t.filter(\n\t\t\t\t(peer) =>\n\t\t\t\t\tpeer.internal.lastFieldId === fieldId &&\n\t\t\t\t\tDate.now() - peer.internal.lastFieldTimestamp! < expirationPeriod,\n\t\t\t);\n\t};\n}\n", "import { EventSubscriber } from '@verdant-web/common';\n\nexport class Heartbeat extends EventSubscriber<{\n\tmissed: () => void;\n\tbeat: () => void;\n}> {\n\tprivate _interval: number;\n\tprivate deadlineLength: number;\n\tprivate nextBeat: NodeJS.Timeout | null = null;\n\tprivate deadline: NodeJS.Timeout | null = null;\n\n\tget interval() {\n\t\treturn this._interval;\n\t}\n\n\tconstructor({\n\t\tinterval = 15 * 1000,\n\t\tdeadlineLength = 3 * 1000,\n\t\trestartOnTabFocus = true,\n\t}: {\n\t\tinterval?: number;\n\t\tdeadlineLength?: number;\n\t\trestartOnTabFocus?: boolean;\n\t} = {}) {\n\t\tsuper();\n\t\tthis._interval = interval;\n\t\tthis.deadlineLength = deadlineLength;\n\t\tif (typeof window !== 'undefined' && restartOnTabFocus) {\n\t\t\twindow.addEventListener('pageshow', () => this.start(true));\n\t\t\tdocument.addEventListener('visibilitychange', () => {\n\t\t\t\tif (document.visibilityState === 'visible') {\n\t\t\t\t\tthis.start(true);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tkeepAlive = () => {\n\t\tif (this.deadline) {\n\t\t\tclearTimeout(this.deadline);\n\t\t\tthis.deadline = null;\n\t\t\tthis.start();\n\t\t}\n\t};\n\n\tstart = (immediate = false) => {\n\t\tthis.stop();\n\t\tif (immediate) {\n\t\t\tthis.beat();\n\t\t} else {\n\t\t\tthis.nextBeat = setTimeout(this.beat, this._interval);\n\t\t}\n\t};\n\n\tstop = () => {\n\t\tif (this.nextBeat) {\n\t\t\tclearTimeout(this.nextBeat);\n\t\t\tthis.nextBeat = null;\n\t\t}\n\t\tif (this.deadline) {\n\t\t\tclearTimeout(this.deadline);\n\t\t\tthis.deadline = null;\n\t\t}\n\t};\n\n\tprivate beat = async () => {\n\t\tthis.emit('beat');\n\t\tthis.deadline = setTimeout(this.onDeadline, this.deadlineLength);\n\t};\n\n\tprivate onDeadline = () => {\n\t\tthis.deadline = null;\n\t\tthis.emit('missed');\n\t};\n\n\t/**\n\t * Only takes affect after the next beat\n\t */\n\tsetInterval = (interval: number) => {\n\t\tthis._interval = interval;\n\t};\n}\n", "import {\n\tClientMessage,\n\tEventSubscriber,\n\tPresenceUpdateMessage,\n\tServerMessage,\n\tVerdantErrorCode,\n\tisVerdantErrorResponse,\n\tthrottle,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { Heartbeat } from './Heartbeat.js';\nimport { PresenceManager } from './PresenceManager.js';\nimport { ServerSyncEndpointProvider } from './ServerSyncEndpointProvider.js';\nimport { SyncTransport, SyncTransportEvents } from './Sync.js';\n\nexport class PushPullSync\n\textends EventSubscriber<SyncTransportEvents>\n\timplements SyncTransport\n{\n\treadonly presence: PresenceManager;\n\tprivate endpointProvider;\n\tprivate heartbeat;\n\tprivate get fetch() {\n\t\treturn this.ctx.environment.fetch;\n\t}\n\n\treadonly mode = 'pull';\n\tprivate ctx;\n\n\tprivate _isConnected = false;\n\tprivate _status: 'active' | 'paused' = 'paused';\n\tprivate _hasSynced = false;\n\n\tconstructor({\n\t\tendpointProvider,\n\t\tpresence,\n\t\tinterval = 15 * 1000,\n\t\tctx,\n\t}: {\n\t\tendpointProvider: ServerSyncEndpointProvider;\n\t\tpresence: PresenceManager;\n\t\tinterval?: number;\n\t\tctx: Context;\n\t}) {\n\t\tsuper();\n\t\tthis.ctx = ctx;\n\t\tthis.presence = presence;\n\t\tthis.endpointProvider = endpointProvider;\n\n\t\tthis.heartbeat = new Heartbeat({\n\t\t\tinterval,\n\t\t});\n\t\tthis.heartbeat.subscribe('beat', this.onHeartbeat);\n\t\tthis.heartbeat.subscribe('missed', this.onHeartbeatMissed);\n\t}\n\n\tsetInterval = (interval: number) => {\n\t\tthis.heartbeat.setInterval(interval);\n\t};\n\n\tget interval() {\n\t\treturn this.heartbeat.interval;\n\t}\n\n\tget hasSynced() {\n\t\treturn this._hasSynced;\n\t}\n\n\tprivate sendRequest = async (messages: ClientMessage[]) => {\n\t\tthis.ctx.log('debug', 'Sending sync request', messages);\n\t\ttry {\n\t\t\tconst { http: host, token } = await this.endpointProvider.getEndpoints();\n\t\t\tconst response = await this.fetch(host, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tmessages,\n\t\t\t\t}),\n\t\t\t\tcredentials: 'include',\n\t\t\t});\n\t\t\tif (response.ok) {\n\t\t\t\tthis.heartbeat.keepAlive();\n\t\t\t\tconst json = (await response.json()) as {\n\t\t\t\t\tmessages: ServerMessage[];\n\t\t\t\t};\n\t\t\t\t// for (const message of json.messages) {\n\t\t\t\t// \tthis.handleServerMessage(message);\n\t\t\t\t// }\n\t\t\t\tconst handlePromise = Promise.all(\n\t\t\t\t\tjson.messages.map(this.handleServerMessage),\n\t\t\t\t);\n\t\t\t\tif (!this._isConnected) {\n\t\t\t\t\tthis._isConnected = true;\n\t\t\t\t\tthis.emit('onlineChange', true);\n\t\t\t\t}\n\t\t\t\tawait handlePromise;\n\t\t\t} else {\n\t\t\t\tthis.ctx.log('error', 'Sync request failed', host, response.status);\n\n\t\t\t\tif (this._isConnected) {\n\t\t\t\t\tthis._isConnected = false;\n\t\t\t\t\tthis.emit('onlineChange', false);\n\t\t\t\t}\n\n\t\t\t\tconst json = await response.json();\n\t\t\t\tif (isVerdantErrorResponse(json)) {\n\t\t\t\t\t// token expired... retry again later after clearing it\n\t\t\t\t\tif (json.code === VerdantErrorCode.TokenExpired) {\n\t\t\t\t\t\tthis.endpointProvider.clearCache();\n\t\t\t\t\t\tthis.heartbeat.keepAlive();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.ctx.log('error', 'Server error', json);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// only keep trying if the error was not 4xx\n\t\t\t\tif (response.status >= 500) {\n\t\t\t\t\tthis.heartbeat.keepAlive();\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (this._isConnected) {\n\t\t\t\tthis._isConnected = false;\n\t\t\t\tthis.emit('onlineChange', false);\n\t\t\t}\n\t\t\tthis.ctx.log('error', error);\n\n\t\t\tthis.heartbeat.keepAlive();\n\t\t}\n\t};\n\n\tprivate handleServerMessage = async (message: ServerMessage) => {\n\t\tif (message.type === 'sync-resp') {\n\t\t\t// we need to ack the nonce to confirm that we received the sync-resp\n\t\t\t// but we can go ahead and preemptively allow ops to be sent\n\t\t\tthis._hasSynced = true;\n\t\t\tif (message.ackThisNonce) {\n\t\t\t\tthis.ctx.log('debug', 'Sending sync ack', message.ackThisNonce);\n\t\t\t\tawait this.sendRequest([\n\t\t\t\t\tawait (\n\t\t\t\t\t\tawait this.ctx.meta\n\t\t\t\t\t).messageCreator.createAck(message.ackThisNonce),\n\t\t\t\t]);\n\t\t\t}\n\t\t}\n\t\tthis.emit('message', message);\n\t};\n\n\t// reduce rate of presence messages sent; each one would trigger an HTTP\n\t// request, which is not ideal if presence is updating rapidly.\n\tthrottledPresenceUpdate = throttle((message: PresenceUpdateMessage) => {\n\t\tthis.sendRequest([message]);\n\t}, 3000);\n\n\tsend = (message: ClientMessage) => {\n\t\tif (this.status !== 'active') {\n\t\t\tthis.ctx.log(\n\t\t\t\t'warn',\n\t\t\t\t'Attempted to send message while sync is not active',\n\t\t\t\tmessage,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\t// only certain messages are sent for pull-based sync.\n\t\tswitch (message.type) {\n\t\t\tcase 'presence-update':\n\t\t\t\treturn this.throttledPresenceUpdate(message);\n\t\t\tcase 'sync':\n\t\t\tcase 'heartbeat':\n\t\t\t\treturn this.sendRequest([message]);\n\t\t\tcase 'op':\n\t\t\t\tif (this._hasSynced) {\n\t\t\t\t\treturn this.sendRequest([message]);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\tstart = async () => {\n\t\tif (this.status === 'active') {\n\t\t\treturn;\n\t\t}\n\t\tthis.ctx.log('debug', 'Starting push-pull sync');\n\t\tawait this.endpointProvider.getEndpoints();\n\t\tthis.heartbeat.start(true);\n\t\tthis._status = 'active';\n\t};\n\tstop(): void {\n\t\tthis.ctx.log('debug', 'Stopping push-pull sync');\n\t\tthis.heartbeat.stop();\n\t\tthis._status = 'paused';\n\t}\n\n\tdestroy = () => {\n\t\tthis.dispose();\n\t\tthis.stop();\n\t};\n\treconnect(): void {\n\t\tthis.heartbeat.start(true);\n\t}\n\n\tignoreIncoming(): void {\n\t\tthis.stop();\n\t}\n\n\t// on a heartbeat, do a sync\n\tprivate onHeartbeat = async () => {\n\t\t// for HTTP sync we send presence first, so that the sync-resp message\n\t\t// will include the client's own presence info and fill in missing profile\n\t\t// data on the first request. otherwise it would have to wait for the second.\n\t\tthis.sendRequest([\n\t\t\tawait (\n\t\t\t\tawait this.ctx.meta\n\t\t\t).messageCreator.createPresenceUpdate(this.presence.self),\n\t\t\tawait (await this.ctx.meta).messageCreator.createSyncStep1(),\n\t\t]);\n\t};\n\n\t// if the server fails to respond in a certain amount of time, we assume\n\t// the connection is lost and go offline.\n\tprivate onHeartbeatMissed = async () => {\n\t\tthis.emit('onlineChange', false);\n\t\tthis.ctx.log('warn', 'Missed heartbeat');\n\t\tthis._isConnected = false;\n\t};\n\n\tsyncOnce = async () => {\n\t\tawait this.sendRequest([\n\t\t\tawait (await this.ctx.meta).messageCreator.createSyncStep1(),\n\t\t]);\n\t};\n\n\tget isConnected(): boolean {\n\t\treturn this._isConnected;\n\t}\n\tget status() {\n\t\treturn this._status;\n\t}\n}\n", "/**\n * The code was extracted from:\n * https://github.com/davidchambers/Base64.js\n */\n\nvar chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\n\nfunction InvalidCharacterError(message) {\n this.message = message;\n}\n\nInvalidCharacterError.prototype = new Error();\nInvalidCharacterError.prototype.name = \"InvalidCharacterError\";\n\nfunction polyfill(input) {\n var str = String(input).replace(/=+$/, \"\");\n if (str.length % 4 == 1) {\n throw new InvalidCharacterError(\n \"'atob' failed: The string to be decoded is not correctly encoded.\"\n );\n }\n for (\n // initialize result and counters\n var bc = 0, bs, buffer, idx = 0, output = \"\";\n // get next character\n (buffer = str.charAt(idx++));\n // character found in table? initialize bit storage and add its ascii value;\n ~buffer &&\n ((bs = bc % 4 ? bs * 64 + buffer : buffer),\n // and if not first of each 4 characters,\n // convert the first 8 bits to one ascii character\n bc++ % 4) ?\n (output += String.fromCharCode(255 & (bs >> ((-2 * bc) & 6)))) :\n 0\n ) {\n // try to find character in table (0-63, not found => -1)\n buffer = chars.indexOf(buffer);\n }\n return output;\n}\n\nexport default (typeof window !== \"undefined\" &&\n window.atob &&\n window.atob.bind(window)) ||\npolyfill;", "import atob from \"./atob\";\n\nfunction b64DecodeUnicode(str) {\n return decodeURIComponent(\n atob(str).replace(/(.)/g, function(m, p) {\n var code = p.charCodeAt(0).toString(16).toUpperCase();\n if (code.length < 2) {\n code = \"0\" + code;\n }\n return \"%\" + code;\n })\n );\n}\n\nexport default function(str) {\n var output = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n switch (output.length % 4) {\n case 0:\n break;\n case 2:\n output += \"==\";\n break;\n case 3:\n output += \"=\";\n break;\n default:\n throw \"Illegal base64url string!\";\n }\n\n try {\n return b64DecodeUnicode(output);\n } catch (err) {\n return atob(output);\n }\n}", "\"use strict\";\n\nimport base64_url_decode from \"./base64_url_decode\";\n\nexport function InvalidTokenError(message) {\n this.message = message;\n}\n\nInvalidTokenError.prototype = new Error();\nInvalidTokenError.prototype.name = \"InvalidTokenError\";\n\nexport default function(token, options) {\n if (typeof token !== \"string\") {\n throw new InvalidTokenError(\"Invalid token specified\");\n }\n\n options = options || {};\n var pos = options.header === true ? 0 : 1;\n try {\n return JSON.parse(base64_url_decode(token.split(\".\")[pos]));\n } catch (e) {\n throw new InvalidTokenError(\"Invalid token specified: \" + e.message);\n }\n}", "import { assert, ReplicaType } from '@verdant-web/common';\nimport { default as jwtDecode } from 'jwt-decode';\nimport { Context } from '../internal.js';\n\nexport interface ServerSyncEndpointProviderConfig {\n\t/**\n\t * The location of the endpoint used to retrieve an\n\t * authorization token for the client.\n\t */\n\tauthEndpoint?: string;\n\t/**\n\t * A custom function to retrieve authorization\n\t * data. Use whatever fetching mechanism you want.\n\t */\n\tfetchAuth?: () => Promise<{\n\t\taccessToken: string;\n\t}>;\n}\n\nexport interface SyncTokenInfo {\n\turl: string;\n\tfileUrl: string;\n\ttype: ReplicaType;\n\tuserId: string;\n\tlibraryId: string;\n\trole?: string;\n}\n\nexport class ServerSyncEndpointProvider {\n\tprivate cached = null as {\n\t\thttp: string;\n\t\twebsocket: string;\n\t\tfiles: string;\n\t\ttoken: string;\n\t} | null;\n\ttokenInfo: SyncTokenInfo | null = null;\n\n\tget type() {\n\t\treturn this.tokenInfo?.type ?? ReplicaType.Realtime;\n\t}\n\n\tconstructor(\n\t\tprivate config: ServerSyncEndpointProviderConfig,\n\t\tprivate ctx: Context,\n\t) {\n\t\tif (!config.authEndpoint && !config.fetchAuth) {\n\t\t\tthrow new Error(\n\t\t\t\t'Either authEndpoint or fetchAuth must be provided to ServerSyncEndpointProvider',\n\t\t\t);\n\t\t}\n\t}\n\n\tgetEndpoints = async () => {\n\t\tif (this.cached) {\n\t\t\treturn this.cached;\n\t\t}\n\n\t\tlet result: { accessToken: string };\n\t\tif (this.config.fetchAuth) {\n\t\t\tresult = await this.config.fetchAuth();\n\t\t} else {\n\t\t\tconst fetchImpl = this.ctx.environment.fetch;\n\t\t\tresult = await fetchImpl(this.config.authEndpoint!, {\n\t\t\t\tcredentials: 'include',\n\t\t\t}).then((res) => {\n\t\t\t\tif (!res.ok) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Auth endpoint returned non-200 response: ${res.status}`,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\treturn res.json();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tassert(result.accessToken, 'No access token provided from auth endpoint');\n\t\tconst decoded = (jwtDecode as any)(result.accessToken);\n\t\tassert(decoded.url, 'No sync endpoint provided from auth endpoint');\n\t\tassert(\n\t\t\tdecoded.type !== undefined,\n\t\t\t'No replica type provided from auth endpoint',\n\t\t);\n\t\tthis.tokenInfo = {\n\t\t\tuserId: decoded.sub,\n\t\t\tlibraryId: decoded.lib,\n\t\t\turl: decoded.url,\n\t\t\tfileUrl: decoded.file,\n\t\t\trole: decoded.role,\n\t\t\ttype: parseInt(decoded.type + '') as ReplicaType,\n\t\t};\n\t\tconst url = new URL(decoded.url);\n\t\turl.protocol = url.protocol.replace('ws', 'http');\n\t\tconst httpEndpoint = url.toString();\n\t\turl.protocol = url.protocol.replace('http', 'ws');\n\t\tconst websocketEndpoint = url.toString();\n\t\tlet fileEndpoint: string = decoded.file;\n\t\tif (!fileEndpoint) {\n\t\t\t// default to http endpoint + '/files';\n\t\t\tconst fileUrl = new URL(httpEndpoint);\n\t\t\tfileUrl.pathname = fileUrl.pathname + '/files';\n\t\t\tfileEndpoint = fileUrl.toString();\n\t\t}\n\t\tthis.cached = {\n\t\t\thttp: httpEndpoint,\n\t\t\twebsocket: websocketEndpoint,\n\t\t\tfiles: fileEndpoint,\n\t\t\ttoken: result.accessToken,\n\t\t};\n\t\treturn this.cached;\n\t};\n\n\tclearCache = () => {\n\t\tthis.cached = null;\n\t};\n}\n", "import { EventSubscriber } from '@verdant-web/common';\n\nexport class BackoffScheduler extends EventSubscriber<{\n\ttrigger: () => void;\n}> {\n\tprivate readonly backoff: Backoff;\n\tprivate timer: NodeJS.Timeout | null = null;\n\tprivate isScheduled = false;\n\n\tconstructor(backoff: Backoff) {\n\t\tsuper();\n\t\tthis.backoff = backoff;\n\t}\n\n\tnext = () => {\n\t\tif (!this.isScheduled) {\n\t\t\tthis.isScheduled = true;\n\t\t\tthis.timer = setTimeout(() => {\n\t\t\t\tthis.emit('trigger');\n\t\t\t\tthis.isScheduled = false;\n\t\t\t\tthis.backoff.next();\n\t\t\t}, this.backoff.current);\n\t\t}\n\t};\n\n\treset = () => {\n\t\tthis.backoff.reset();\n\t\tif (this.timer) {\n\t\t\tclearTimeout(this.timer);\n\t\t\tthis.timer = null;\n\t\t}\n\t};\n}\n\nexport class Backoff {\n\tcurrent = 0;\n\tprivate readonly max: number;\n\tprivate readonly factor: number;\n\n\tconstructor(initial: number, max: number, factor: number) {\n\t\tthis.current = initial;\n\t\tthis.max = max;\n\t\tthis.factor = factor;\n\t}\n\n\tnext = () => {\n\t\tthis.current = Math.min(this.max, Math.max(1, this.current) * this.factor);\n\t};\n\n\treset = () => {\n\t\tthis.current = 0;\n\t};\n}\n", "import {\n\tClientMessage,\n\tEventSubscriber,\n\tServerMessage,\n} from '@verdant-web/common';\nimport { Backoff, BackoffScheduler } from '../BackoffScheduler.js';\nimport { Context } from '../context/context.js';\nimport { Heartbeat } from './Heartbeat.js';\nimport { PresenceManager } from './PresenceManager.js';\nimport { ServerSyncEndpointProvider } from './ServerSyncEndpointProvider.js';\nimport { SyncTransport, SyncTransportEvents } from './Sync.js';\n\nexport class WebSocketSync\n\textends EventSubscriber<SyncTransportEvents>\n\timplements SyncTransport\n{\n\treadonly presence: PresenceManager;\n\tprivate socket: WebSocket | null = null;\n\t// messages awaiting websocket connection to send\n\tprivate connectQueue: ClientMessage[] = [];\n\t// messages awaiting sync response to send\n\tprivate syncQueue: ClientMessage[] = [];\n\t// messages waiting for sync to finish\n\tprivate incomingQueue: ServerMessage[] = [];\n\tprivate endpointProvider;\n\tprivate _status: 'active' | 'paused' = 'paused';\n\tprivate synced = false;\n\tprivate hasStartedSync = false;\n\tprivate _ignoreIncoming = false;\n\n\treadonly mode = 'realtime';\n\tprivate ctx: Context;\n\n\tprivate heartbeat = new Heartbeat();\n\n\tprivate reconnectScheduler = new BackoffScheduler(\n\t\tnew Backoff(2_000, 60_000, 1.5),\n\t);\n\n\tconstructor({\n\t\tendpointProvider,\n\t\tctx,\n\t\tpresence,\n\t}: {\n\t\tendpointProvider: ServerSyncEndpointProvider;\n\t\tctx: Context;\n\t\tpresence: PresenceManager;\n\t}) {\n\t\tsuper();\n\t\tthis.ctx = ctx;\n\t\tthis.endpointProvider = endpointProvider;\n\t\tthis.presence = presence;\n\n\t\tthis.reconnectScheduler.subscribe('trigger', this.initializeSocket);\n\t\tthis.heartbeat.subscribe('beat', this.sendHeartbeat);\n\t\twindow.addEventListener('beforeunload', () => {\n\t\t\treturn this.sendDisconnecting();\n\t\t});\n\t}\n\n\tget hasSynced() {\n\t\treturn this.synced;\n\t}\n\n\tprivate onOpen = () => {\n\t\tif (!this.socket) {\n\t\t\tthrow new Error('Invalid sync state: online but socket is null');\n\t\t}\n\t\tthis.synced = false;\n\t\tif (this.connectQueue.length) {\n\t\t\tfor (const msg of this.connectQueue) {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'Sending queued message',\n\t\t\t\t\tJSON.stringify(msg, null, 2),\n\t\t\t\t);\n\t\t\t\tthis.socket.send(JSON.stringify(msg));\n\t\t\t}\n\t\t\tthis.connectQueue = [];\n\t\t}\n\t\tthis.ctx.log('debug', 'Sync connected');\n\t\tthis.onOnlineChange(true);\n\t};\n\n\tprivate onOnlineChange = async (online: boolean) => {\n\t\tthis.ctx.log('info', 'Socket online change', online);\n\t\tif (this.disposed) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.ctx.closing) return;\n\t\tif (!online) {\n\t\t\tthis.hasStartedSync = false;\n\t\t\tthis.synced = false;\n\t\t\tthis.heartbeat.stop();\n\t\t} else {\n\t\t\tthis.ctx.log('debug', 'Starting sync');\n\t\t\tthis.hasStartedSync = true;\n\t\t\tthis.synced = false;\n\t\t\tconst meta = await this.ctx.meta;\n\t\t\tthis.send(\n\t\t\t\tawait meta.messageCreator.createPresenceUpdate(this.presence.self),\n\t\t\t);\n\t\t\tthis.send(await meta.messageCreator.createSyncStep1());\n\t\t\tthis.heartbeat.start();\n\t\t}\n\t\tthis.emit('onlineChange', online);\n\t};\n\n\tprivate onMessage = async (event: MessageEvent) => {\n\t\tthis.reconnectScheduler.reset();\n\t\tif (this._ignoreIncoming) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'warn',\n\t\t\t\t'Ignoring incoming message (ignore incoming flag set)',\n\t\t\t\tevent.data,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst message = JSON.parse(event.data) as ServerMessage;\n\t\tthis.ctx.log('debug', 'Received', message.type, 'message');\n\t\tswitch (message.type) {\n\t\t\tcase 'sync-resp':\n\t\t\t\tif (message.ackThisNonce) {\n\t\t\t\t\t// we need to send the ack to confirm we got the response\n\t\t\t\t\tthis.send(\n\t\t\t\t\t\tawait (\n\t\t\t\t\t\t\tawait this.ctx.meta\n\t\t\t\t\t\t).messageCreator.createAck(message.ackThisNonce),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthis.hasStartedSync = true;\n\t\t\t\tthis.synced = true;\n\t\t\t\tif (this.syncQueue.length) {\n\t\t\t\t\tif (message.overwriteLocalData) {\n\t\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t\t'warn',\n\t\t\t\t\t\t\t'Overwriting local data - dropping outgoing message queue',\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.syncQueue = [];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor (const msg of this.syncQueue) {\n\t\t\t\t\t\t\tthis.send(msg);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.syncQueue = [];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.emit('message', message);\n\t\t\t\tif (this.incomingQueue.length) {\n\t\t\t\t\tfor (const msg of this.incomingQueue) {\n\t\t\t\t\t\tthis.emit('message', msg);\n\t\t\t\t\t}\n\t\t\t\t\tthis.incomingQueue = [];\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'need-since':\n\t\t\tcase 'presence-changed':\n\t\t\tcase 'presence-offline':\n\t\t\t\tthis.emit('message', message);\n\t\t\t\tbreak;\n\t\t\tcase 'op-re':\n\t\t\t\tif (!this.synced) {\n\t\t\t\t\tthis.ctx.log(\n\t\t\t\t\t\t'debug',\n\t\t\t\t\t\t`Enqueueing op-re message because sync hasn't finished yet`,\n\t\t\t\t\t\tmessage,\n\t\t\t\t\t);\n\t\t\t\t\tthis.incomingQueue.push(message);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tthis.emit('message', message);\n\t\t\t\tbreak;\n\t\t\tcase 'heartbeat-response':\n\t\t\t\tthis.heartbeat.keepAlive();\n\t\t\t\tthis.emit('message', message);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif (this.synced) {\n\t\t\t\t\tthis.emit('message', message);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\tprivate onError = (event: Event) => {\n\t\tthis.ctx.log('error', 'Sync socket error', event, event.target);\n\t\tif (this.disposed) return;\n\t\t// this could be an auth error which requires us to get a new token\n\t\t// so clearing the endpoint cache to force a refresh of the token too\n\t\tthis.endpointProvider.clearCache();\n\t\tthis.reconnectScheduler.next();\n\n\t\tthis.ctx.log('info', `Attempting reconnect to websocket sync`);\n\t};\n\n\tprivate onClose = (event: CloseEvent) => {\n\t\tthis.ctx.log('info', 'Sync socket disconnected', event.code);\n\t\tthis.onOnlineChange(false);\n\t\tif (this.disposed) return;\n\t\tthis.reconnectScheduler.next();\n\t\tthis.ctx.log('info', `Attempting reconnect to websocket sync`);\n\t};\n\n\tprivate initializeSocket = async () => {\n\t\tconst endpoint = await this.endpointProvider.getEndpoints();\n\t\t// abusing protocols to pass the auth token\n\t\tthis.socket = new this.ctx.environment.WebSocket(endpoint.websocket, [\n\t\t\t'Bearer',\n\t\t\tendpoint.token,\n\t\t]);\n\t\tthis.socket.addEventListener('message', this.onMessage);\n\t\tthis.socket.addEventListener('open', this.onOpen);\n\t\tthis.socket.addEventListener('error', this.onError);\n\t\tthis.socket.addEventListener('close', this.onClose);\n\t\treturn this.socket;\n\t};\n\n\tprivate sendHeartbeat = async () => {\n\t\tthis.send(await (await this.ctx.meta).messageCreator.createHeartbeat());\n\t};\n\n\treconnect = () => {\n\t\tthis.stop();\n\t\tthis.start();\n\t};\n\n\tprivate canSkipSyncWait = (message: ClientMessage) => {\n\t\treturn (\n\t\t\tmessage.type === 'sync' ||\n\t\t\tmessage.type === 'presence-update' ||\n\t\t\tmessage.type === 'sync-ack' ||\n\t\t\tmessage.type === 'heartbeat'\n\t\t);\n\t};\n\n\tsend = (message: ClientMessage) => {\n\t\tif (this.status !== 'active') {\n\t\t\tthis.ctx.log(\n\t\t\t\t'debug',\n\t\t\t\t'Ignoring outgoing message',\n\t\t\t\tmessage.type,\n\t\t\t\t'sync is not active',\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// wait until a sync has started before doing anything other than sync.\n\t\t// new \"op\" messages can arrive before sync has started, so we need to wait\n\t\tif (!this.hasStartedSync && !this.canSkipSyncWait(message)) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'debug',\n\t\t\t\t'Ignoring outgoing message',\n\t\t\t\tmessage.type,\n\t\t\t\t'still waiting to begin initial sync',\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.canSkipSyncWait(message)) {\n\t\t\tif (this.socket?.readyState === WEBSOCKET_OPEN) {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'Sending message',\n\t\t\t\t\tJSON.stringify(message, null, 2),\n\t\t\t\t);\n\t\t\t\tthis.socket!.send(JSON.stringify(message));\n\t\t\t} else {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'Enqueueing message until socket is open',\n\t\t\t\t\tJSON.stringify(message, null, 2),\n\t\t\t\t);\n\t\t\t\tthis.connectQueue.push(message);\n\t\t\t}\n\t\t} else if (this.synced) {\n\t\t\tif (this.socket?.readyState === WEBSOCKET_OPEN) {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'debug',\n\t\t\t\t\t'Sending message',\n\t\t\t\t\tJSON.stringify(message, null, 2),\n\t\t\t\t);\n\t\t\t\tthis.socket.send(JSON.stringify(message));\n\t\t\t}\n\t\t} else if (this.hasStartedSync) {\n\t\t\tthis.ctx.log(\n\t\t\t\t'debug',\n\t\t\t\t'Enqueueing message until synced',\n\t\t\t\tJSON.stringify(message, null, 2),\n\t\t\t);\n\t\t\tthis.syncQueue.push(message);\n\t\t}\n\t};\n\n\tsendDisconnecting = async (reason = 'client-shutdown') => {\n\t\treturn this.send(\n\t\t\tawait (await this.ctx.meta).messageCreator.createDisconnecting(reason),\n\t\t);\n\t};\n\n\tdestroy = () => {\n\t\tthis.dispose();\n\t\tthis.stop();\n\t};\n\n\tstart = async () => {\n\t\tif (this.socket) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.initializeSocket();\n\t\tthis._status = 'active';\n\t};\n\n\tstop = async () => {\n\t\tawait this.sendDisconnecting();\n\t\tthis.socket?.removeEventListener('message', this.onMessage);\n\t\tthis.socket?.removeEventListener('close', this.onClose);\n\t\tif (this.socket?.readyState === WEBSOCKET_OPEN) {\n\t\t\tthis.socket.close();\n\t\t}\n\t\tthis.socket = null;\n\t\tthis._status = 'paused';\n\t};\n\n\tignoreIncoming(): void {\n\t\tthis.incomingQueue = [];\n\t\tthis._ignoreIncoming = true;\n\t}\n\n\tget isConnected() {\n\t\treturn this.socket?.readyState === WEBSOCKET_OPEN;\n\t}\n\n\tget status() {\n\t\treturn this._status;\n\t}\n}\n\nconst WEBSOCKET_OPEN = 1;\n", "import {\n\tClientMessage,\n\tDocumentBaseline,\n\tEventSubscriber,\n\tFileData,\n\tOperation,\n\tReplicaType,\n\trewriteAuthzOriginator,\n\tServerMessage,\n\tVerdantError,\n\tVerdantInternalPresence,\n} from '@verdant-web/common';\nimport { Context } from '../context/context.js';\nimport { attemptToRegisterBackgroundSync } from './background.js';\nimport { FilePullResult, FileSync, FileUploadResult } from './FileSync.js';\nimport { HANDLE_MESSAGE, PresenceManager } from './PresenceManager.js';\nimport { PushPullSync } from './PushPullSync.js';\nimport {\n\tServerSyncEndpointProvider,\n\tServerSyncEndpointProviderConfig,\n} from './ServerSyncEndpointProvider.js';\nimport { WebSocketSync } from './WebSocketSync.js';\n\ntype SyncEvents = {\n\tonlineChange: (isOnline: boolean) => void;\n\tsyncingChange: (syncing: boolean) => void;\n\tsynced: () => void;\n\t/** When the server has lost data and re-requests data from the past */\n\tserverReset: (since: string | null) => void;\n};\n\nexport type SyncTransportEvents = SyncEvents & {\n\tmessage: (message: ServerMessage) => void;\n};\n\nexport interface SyncTransport extends EventSubscriber<SyncTransportEvents> {\n\treadonly presence: PresenceManager;\n\n\treadonly mode: SyncTransportMode;\n\treadonly hasSynced: boolean;\n\n\tsend(message: ClientMessage): void;\n\n\tstart(): Promise<void>;\n\tignoreIncoming(): void;\n\tstop(): Promise<void> | void;\n\n\tdestroy(): void;\n\n\treconnect(): void;\n\n\treadonly isConnected: boolean;\n\treadonly status: 'active' | 'paused';\n}\n\nexport interface Sync<Presence = any, Profile = any>\n\textends EventSubscriber<SyncEvents> {\n\tsetMode(mode: SyncTransportMode): void;\n\tsetPullInterval(interval: number): void;\n\treadonly pullInterval: number;\n\tuploadFile(data: FileData): Promise<FileUploadResult>;\n\tgetFile(fileId: string): Promise<FilePullResult>;\n\treadonly presence: PresenceManager<Profile, Presence>;\n\tsend(message: ClientMessage): void;\n\tstart(): Promise<void>;\n\tstop(): Promise<void> | void;\n\tignoreIncoming(): void;\n\tdestroy(): void;\n\treconnect(): void;\n\tsyncOnce(): Promise<void>;\n\treadonly isConnected: boolean;\n\treadonly status: 'active' | 'paused';\n\treadonly mode: SyncTransportMode;\n\treadonly hasSynced: boolean;\n}\n\nexport class NoSync<Presence = any, Profile = any>\n\textends EventSubscriber<SyncEvents>\n\timplements Sync<Presence, Profile>\n{\n\treadonly mode = 'pull';\n\treadonly hasSynced = false;\n\n\tpublic send(): void {}\n\n\tpublic async start(): Promise<void> {}\n\n\tpublic stop(): void {}\n\n\tpublic ignoreIncoming(): void {}\n\n\tpublic destroy = () => {};\n\n\tpublic reconnect(): void {}\n\n\tpublic setMode(): void {}\n\tpublic setPullInterval(): void {}\n\n\tpublic readonly isConnected = false;\n\tpublic readonly status = 'paused';\n\tpublic readonly pullInterval = 0;\n\n\tpublic readonly presence;\n\n\tconstructor(ctx: Context) {\n\t\tsuper();\n\t\tthis.presence = new PresenceManager({\n\t\t\tinitialPresence: null as any,\n\t\t\tdefaultProfile: null as any,\n\t\t\tctx,\n\t\t});\n\t}\n\n\tuploadFile = async () => {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tretry: false,\n\t\t};\n\t};\n\n\tgetFile = async (): Promise<FilePullResult> => {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: 'Sync is not active',\n\t\t};\n\t};\n\n\tsyncOnce: () => Promise<void> = async () => {};\n}\n\nexport type SyncTransportMode = 'realtime' | 'pull';\n\nexport interface ServerSyncOptions<Profile = any, Presence = any>\n\textends ServerSyncEndpointProviderConfig {\n\t/**\n\t * When a client first connects, it will use this presence value.\n\t */\n\tinitialPresence: Presence;\n\t/**\n\t * Before connecting to the server, the local client will have\n\t * this value for their profile data. You can either cache and store\n\t * profile data from a previous connection or provide defaults like\n\t * empty strings.\n\t */\n\tdefaultProfile: Profile;\n\n\t/**\n\t * Provide `false` to disable transport selection. Transport selection\n\t * automatically switches between HTTP and WebSocket based sync depending\n\t * on the number of peers connected. If a user is alone, they will use\n\t * HTTP push/pull to sync changes. If another user joins, both users will\n\t * be upgraded to websockets.\n\t *\n\t * Provide `peers-only` to only automatically use websockets if other\n\t * users connect, but not if another device for the current user connects.\n\t * By default, automatic transport selection will upgrade to websockets if\n\t * another device from the current user connects, but if realtime sync is\n\t * not necessary for such cases, you can save bandwidth by disabling this.\n\t *\n\t * Turning off this feature allows you more control over the transport\n\t * which can be useful for low-power devices or to save server traffic.\n\t * To modify transport modes manually, utilize `client.sync.setMode`.\n\t * The built-in behavior is essentially switching modes based on\n\t * the number of peers detected by client.sync.presence.\n\t */\n\tautomaticTransportSelection?: boolean | 'peers-only';\n\tinitialTransport?: SyncTransportMode;\n\tautoStart?: boolean;\n\t/**\n\t * Optionally specify an interval, in milliseconds, to poll the server\n\t * when in pull mode.\n\t */\n\tpullInterval?: number;\n\t/**\n\t * Presence updates are batched to reduce number of requests / messages\n\t * sent to the server. You can specify the batching time slice, in milliseconds,\n\t */\n\tpresenceUpdateBatchTimeout?: number;\n\t/**\n\t * Experimental: sync messages over a broadcast channel between tabs.\n\t * Fixes tabs not reactively updating to changes when other tabs are open,\n\t * but is not yet thoroughly vetted.\n\t */\n\tuseBroadcastChannel?: boolean;\n\t/**\n\t * Listen for outgoing messages from the client to the server.\n\t * Not sure why you want to do this, but be careful.\n\t */\n\tonOutgoingMessage?: (message: ClientMessage) => void;\n\n\tEXPERIMENTAL_backgroundSync?: boolean;\n}\n\nexport class ServerSync<Presence = any, Profile = any>\n\textends EventSubscriber<SyncEvents>\n\timplements Sync<Presence, Profile>\n{\n\tprivate webSocketSync: WebSocketSync;\n\tprivate pushPullSync: PushPullSync;\n\tprivate fileSync: FileSync;\n\tprivate activeSync: SyncTransport;\n\tprivate endpointProvider;\n\tprivate onData: (data: {\n\t\toperations: Operation[];\n\t\tbaselines?: DocumentBaseline[];\n\t\treset?: boolean;\n\t}) => Promise<void>;\n\tprivate broadcastChannel: BroadcastChannel | null = null;\n\tprivate _activelySyncing = false;\n\tprivate _hasSynced = false;\n\n\treadonly presence: PresenceManager<Profile, Presence>;\n\n\tprivate onOutgoingMessage?: (message: ClientMessage) => void;\n\n\tprivate ctx;\n\n\tconstructor(\n\t\t{\n\t\t\tauthEndpoint,\n\t\t\tfetchAuth,\n\t\t\tinitialPresence,\n\t\t\tautomaticTransportSelection = true,\n\t\t\tautoStart,\n\t\t\tinitialTransport,\n\t\t\tpullInterval,\n\t\t\tpresenceUpdateBatchTimeout,\n\t\t\tdefaultProfile,\n\t\t\tuseBroadcastChannel,\n\t\t\tonOutgoingMessage,\n\t\t\tEXPERIMENTAL_backgroundSync,\n\t\t}: ServerSyncOptions<Profile, Presence>,\n\t\t{\n\t\t\tctx,\n\t\t\tonData,\n\t\t}: {\n\t\t\tctx: Context;\n\t\t\tonData: (data: {\n\t\t\t\toperations: Operation[];\n\t\t\t\tbaselines?: DocumentBaseline[];\n\t\t\t\treset?: boolean;\n\t\t\t}) => Promise<void>;\n\t\t},\n\t) {\n\t\tsuper();\n\t\tthis.onData = onData;\n\t\tthis.ctx = ctx;\n\t\tthis.onOutgoingMessage = onOutgoingMessage;\n\t\tthis.presence = new PresenceManager({\n\t\t\tinitialPresence,\n\t\t\tdefaultProfile,\n\t\t\tupdateBatchTimeout: presenceUpdateBatchTimeout,\n\t\t\tctx,\n\t\t});\n\t\tthis.endpointProvider = new ServerSyncEndpointProvider(\n\t\t\t{\n\t\t\t\tauthEndpoint,\n\t\t\t\tfetchAuth,\n\t\t\t},\n\t\t\tctx,\n\t\t);\n\n\t\tthis.webSocketSync = new WebSocketSync({\n\t\t\tendpointProvider: this.endpointProvider,\n\t\t\tpresence: this.presence,\n\t\t\tctx,\n\t\t});\n\t\tthis.pushPullSync = new PushPullSync({\n\t\t\tendpointProvider: this.endpointProvider,\n\t\t\tpresence: this.presence,\n\t\t\tinterval: pullInterval,\n\t\t\tctx,\n\t\t});\n\t\tthis.fileSync = new FileSync({\n\t\t\tendpointProvider: this.endpointProvider,\n\t\t\tctx,\n\t\t});\n\t\tif (useBroadcastChannel && 'BroadcastChannel' in window) {\n\t\t\tthis.broadcastChannel = new BroadcastChannel(`verdant-${ctx.namespace}`);\n\t\t\tthis.broadcastChannel.addEventListener(\n\t\t\t\t'message',\n\t\t\t\tthis.handleBroadcastChannelMessage,\n\t\t\t);\n\t\t}\n\t\tctx.log(\n\t\t\t'info',\n\t\t\t'Sync initialized with transport:',\n\t\t\tinitialTransport ?? 'pull',\n\t\t);\n\t\tif (initialTransport === 'realtime') {\n\t\t\tthis.activeSync = this.webSocketSync;\n\t\t} else {\n\t\t\tthis.activeSync = this.pushPullSync;\n\t\t}\n\n\t\tthis.presence.subscribe('update', this.handlePresenceUpdate);\n\n\t\tctx.internalEvents.subscribe('outgoingSyncMessage', this.send);\n\t\tthis.webSocketSync.subscribe('message', this.handleMessage);\n\t\tthis.webSocketSync.subscribe('onlineChange', this.handleOnlineChange);\n\n\t\tthis.pushPullSync.subscribe('message', this.handleMessage);\n\t\tthis.pushPullSync.subscribe('onlineChange', this.handleOnlineChange);\n\n\t\tif (automaticTransportSelection && this.canDoRealtime) {\n\t\t\t// automatically shift between transport modes depending\n\t\t\t// on whether any peers are present (matching view if\n\t\t\t// applicable)\n\t\t\tconst decideIfUpgrade = () => {\n\t\t\t\tif (switchoverTimeout) {\n\t\t\t\t\tclearTimeout(switchoverTimeout);\n\t\t\t\t}\n\t\t\t\tconst hasPeers = this.presence.getViewPeers().length > 0;\n\t\t\t\tconst shouldUpgrade =\n\t\t\t\t\thasPeers ||\n\t\t\t\t\t(automaticTransportSelection !== 'peers-only' &&\n\t\t\t\t\t\tthis.presence.selfReplicaIds.size > 1);\n\t\t\t\tif (shouldUpgrade && this.mode === 'pull') {\n\t\t\t\t\tthis.setMode('realtime');\n\t\t\t\t} else if (!shouldUpgrade && this.mode === 'realtime') {\n\t\t\t\t\t// wait 1 second then switch to pull mode if still empty\n\t\t\t\t\tswitchoverTimeout = setTimeout(() => {\n\t\t\t\t\t\tif (this.presence.getViewPeers().length === 0) {\n\t\t\t\t\t\t\tthis.setMode('pull');\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 1000);\n\t\t\t\t}\n\t\t\t};\n\t\t\tlet switchoverTimeout: NodeJS.Timeout;\n\t\t\tthis.presence.subscribe('peersChanged', decideIfUpgrade);\n\t\t\tif (automaticTransportSelection !== 'peers-only') {\n\t\t\t\tthis.presence.subscribe('selfChanged', decideIfUpgrade);\n\t\t\t}\n\t\t}\n\n\t\tif (autoStart) {\n\t\t\tthis.start();\n\t\t}\n\n\t\tif (EXPERIMENTAL_backgroundSync) {\n\t\t\tattemptToRegisterBackgroundSync();\n\t\t}\n\t}\n\n\tget canDoRealtime() {\n\t\treturn (\n\t\t\tthis.endpointProvider.type === ReplicaType.Realtime ||\n\t\t\tthis.endpointProvider.type === ReplicaType.PassiveRealtime ||\n\t\t\tthis.endpointProvider.type === ReplicaType.ReadOnlyRealtime\n\t\t);\n\t}\n\n\tget syncing() {\n\t\treturn this._activelySyncing;\n\t}\n\n\tget hasSynced() {\n\t\treturn this._hasSynced;\n\t}\n\n\tprivate handleBroadcastChannelMessage = (event: MessageEvent) => {\n\t\tif (event.data.type === 'sync') {\n\t\t\tthis.handleMessage(event.data.message, { source: 'broadcastChannel' });\n\t\t}\n\t};\n\n\tprivate handleMessage = async (\n\t\tmessage: ServerMessage,\n\t\t{ source }: { source: 'network' | 'broadcastChannel' } = {\n\t\t\tsource: 'network',\n\t\t},\n\t) => {\n\t\t// cancel if client is shutting down\n\t\tif (this.ctx.closing) return;\n\n\t\t// TODO: move this into metadata\n\t\tif (message.type === 'op-re' || message.type === 'sync-resp') {\n\t\t\tfor (const op of message.operations) {\n\t\t\t\tthis.ctx.time.update(op.timestamp);\n\t\t\t}\n\t\t}\n\n\t\tthis.ctx.log('debug', 'sync message', JSON.stringify(message, null, 2));\n\t\tswitch (message.type) {\n\t\t\tcase 'op-re':\n\t\t\t\tawait this.onData({\n\t\t\t\t\toperations: message.operations,\n\t\t\t\t\tbaselines: message.baselines,\n\t\t\t\t});\n\t\t\t\tif (message.globalAckTimestamp) {\n\t\t\t\t\tawait (await this.ctx.meta).setGlobalAck(message.globalAckTimestamp);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'global-ack':\n\t\t\t\tawait (await this.ctx.meta).setGlobalAck(message.timestamp);\n\t\t\t\tbreak;\n\t\t\tcase 'sync-resp':\n\t\t\t\tthis._activelySyncing = true;\n\t\t\t\tthis.emit('syncingChange', true);\n\t\t\t\tawait this.onData({\n\t\t\t\t\toperations: message.operations,\n\t\t\t\t\tbaselines: message.baselines,\n\t\t\t\t\treset: message.overwriteLocalData,\n\t\t\t\t});\n\n\t\t\t\tif (message.globalAckTimestamp) {\n\t\t\t\t\tawait (await this.ctx.meta).setGlobalAck(message.globalAckTimestamp);\n\t\t\t\t}\n\n\t\t\t\tawait (await this.ctx.meta).updateLastSynced(message.ackedTimestamp);\n\t\t\t\tthis._activelySyncing = false;\n\t\t\t\tthis.emit('syncingChange', false);\n\t\t\t\tthis._hasSynced = true;\n\t\t\t\tthis.emit('synced');\n\t\t\t\tbreak;\n\t\t\tcase 'need-since':\n\t\t\t\tthis.emit('serverReset', message.since);\n\t\t\t\t(await this.ctx.files).onServerReset(message.since);\n\t\t\t\tthis.activeSync.send(\n\t\t\t\t\tawait (\n\t\t\t\t\t\tawait this.ctx.meta\n\t\t\t\t\t).messageCreator.createSyncStep1(message.since),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase 'server-ack':\n\t\t\t\tawait (await this.ctx.meta).updateLastSynced(message.timestamp);\n\t\t}\n\n\t\t// avoid rebroadcasting messages\n\t\tif (source === 'network') {\n\t\t\tthis.broadcastChannel?.postMessage({\n\t\t\t\ttype: 'sync',\n\t\t\t\tmessage,\n\t\t\t});\n\t\t}\n\n\t\t// update presence if necessary\n\t\tthis.presence[HANDLE_MESSAGE](\n\t\t\tawait (await this.ctx.meta).getLocalReplica(),\n\t\t\tmessage,\n\t\t);\n\t};\n\tprivate handleOnlineChange = async (online: boolean) => {\n\t\tthis.emit('onlineChange', online);\n\n\t\t// if online, attempt to upload any unsynced files.\n\t\tif (online) {\n\t\t\tconst unsyncedFiles = await (await this.ctx.files).listUnsynced();\n\t\t\tconst results = await Promise.allSettled(\n\t\t\t\tunsyncedFiles.map((file) => this.fileSync.uploadFile(file)),\n\t\t\t);\n\t\t\tif (results.some((r) => r.status === 'rejected')) {\n\t\t\t\tthis.ctx.log(\n\t\t\t\t\t'error',\n\t\t\t\t\t'Failed to upload unsynced files',\n\t\t\t\t\tresults\n\t\t\t\t\t\t.filter((r): r is PromiseRejectedResult => r.status === 'rejected')\n\t\t\t\t\t\t.map((r) => r.reason),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t};\n\tprivate handlePresenceUpdate = async (data: {\n\t\tpresence?: Presence;\n\t\tinternal?: VerdantInternalPresence;\n\t}) => {\n\t\tthis.send(\n\t\t\tawait (await this.ctx.meta).messageCreator.createPresenceUpdate(data),\n\t\t);\n\t};\n\n\tsetMode = (transport: SyncTransportMode) => {\n\t\tif (transport === 'realtime' && !this.canDoRealtime) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot switch to realtime mode, because the current auth token does not allow it`,\n\t\t\t);\n\t\t}\n\n\t\tlet newSync: SyncTransport;\n\t\tif (transport === 'realtime') {\n\t\t\tnewSync = this.webSocketSync;\n\t\t} else {\n\t\t\tnewSync = this.pushPullSync;\n\t\t}\n\n\t\tif (newSync === this.activeSync) return;\n\t\tthis.ctx.log('debug', 'switching to', transport, 'mode');\n\n\t\t// transfer state to new sync\n\t\tif (this.activeSync.status === 'active') {\n\t\t\tnewSync.start();\n\t\t}\n\t\tthis.activeSync.stop();\n\t\tthis.activeSync = newSync;\n\t};\n\n\tsetPullInterval = (interval: number) => {\n\t\tthis.pushPullSync.setInterval(interval);\n\t};\n\n\tget pullInterval() {\n\t\treturn this.pushPullSync.interval;\n\t}\n\n\tsend = async (message: ClientMessage) => {\n\t\tif (this.activeSync.status === 'active') {\n\t\t\t// before sync, replace 'originator' authz subjects\n\t\t\t// with token userId. This is the easiest place to\n\t\t\t// do this and allows the rest of the system to be\n\t\t\t// ambivalent about user identity when assigning\n\t\t\t// authorization for the current user.\n\t\t\tconst userId = this.endpointProvider.tokenInfo?.userId;\n\t\t\tif (!userId) {\n\t\t\t\tthrow new VerdantError(\n\t\t\t\t\tVerdantError.Code.Unexpected,\n\t\t\t\t\tundefined,\n\t\t\t\t\t'Active sync has invalid token info',\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (message.type === 'sync' || message.type === 'op') {\n\t\t\t\trewriteAuthzOriginator(message, userId);\n\t\t\t}\n\t\t\tthis.activeSync.send(message);\n\t\t\tthis.onOutgoingMessage?.(message);\n\t\t}\n\t};\n\n\tuploadFile = async (info: FileData) => {\n\t\tthis.ctx.log('info', 'Uploading file', {\n\t\t\tname: info.name,\n\t\t\ttype: info.type,\n\t\t\tid: info.id,\n\t\t\tsize: info.file?.size,\n\t\t});\n\t\tif (this.activeSync.status === 'active') {\n\t\t\treturn this.fileSync.uploadFile(info);\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tretry: false,\n\t\t\t\terror: 'Sync is not active',\n\t\t\t};\n\t\t}\n\t};\n\n\tgetFile = async (id: string) => {\n\t\t// TODO: should this error? or just try anyway?\n\t\tif (this.activeSync.status === 'active') {\n\t\t\treturn this.fileSync.getFile(id);\n\t\t} else {\n\t\t\t// wait for sync to start, up to 5 seconds\n\t\t\tawait this.getSyncStartPromise();\n\t\t\tif (this.activeSync.status === 'paused') {\n\t\t\t\tthrow new VerdantError(\n\t\t\t\t\tVerdantError.Code.Offline,\n\t\t\t\t\tundefined,\n\t\t\t\t\t'Sync is not active',\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn this.fileSync.getFile(id);\n\t\t}\n\t};\n\n\tprivate getSyncStartPromise = (timeout = 5000) => {\n\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\tconst timeoutHandle = setTimeout(() => {\n\t\t\t\treject(new Error('Sync did not start in time'));\n\t\t\t\tunsubscribe();\n\t\t\t}, timeout);\n\t\t\tconst unsubscribe = this.subscribe('onlineChange', (online: boolean) => {\n\t\t\t\tif (online) {\n\t\t\t\t\tclearTimeout(timeoutHandle);\n\t\t\t\t\tunsubscribe();\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t};\n\n\tpublic start = () => {\n\t\tthis.ctx.log('info', 'Starting sync');\n\t\treturn this.activeSync.start();\n\t};\n\n\tpublic stop = () => {\n\t\tthis.ctx.log('info', 'Stopping sync');\n\t\treturn this.activeSync.stop();\n\t};\n\n\tpublic ignoreIncoming(): void {\n\t\tthis.activeSync.ignoreIncoming();\n\t}\n\n\tpublic destroy = () => {\n\t\tthis.dispose();\n\t\tthis.webSocketSync.destroy();\n\t\tthis.pushPullSync.destroy();\n\t};\n\n\tpublic reconnect = () => {\n\t\treturn this.activeSync.reconnect();\n\t};\n\n\t/**\n\t * Runs one isolated sync cycle over HTTP. This is useful for\n\t * syncing via a periodic background job in a service worker,\n\t * which keeps a client up to date while the app isn't open.\n\t */\n\tpublic syncOnce = () => {\n\t\treturn this.pushPullSync.syncOnce();\n\t};\n\n\tpublic get isConnected(): boolean {\n\t\treturn this.activeSync.isConnected;\n\t}\n\n\tpublic get status() {\n\t\treturn this.activeSync.status;\n\t}\n\n\tpublic get mode() {\n\t\treturn this.activeSync.mode;\n\t}\n}\n", "import {\n\tDocumentBaseline,\n\tgetTimestampSchemaVersion,\n\tOperation,\n} from '@verdant-web/common';\n\nexport function getLatestVersion(data: {\n\toperations: Operation[];\n\tbaselines?: DocumentBaseline[];\n}) {\n\tconst timestamps = data.operations\n\t\t.map((op) => op.timestamp)\n\t\t.concat(data.baselines?.map((b) => b.timestamp) ?? []);\n\tconst latestVersion = timestamps.reduce((v, ts) => {\n\t\tconst tsVersion = getTimestampSchemaVersion(ts);\n\t\tif (tsVersion > v) {\n\t\t\treturn tsVersion;\n\t\t}\n\t\treturn v;\n\t}, 1);\n\n\treturn latestVersion;\n}\n", "import {\n\tdebounce,\n\tDocumentBaseline,\n\tEventSubscriber,\n\tFileData,\n\tOperation,\n\tVerdantError,\n} from '@verdant-web/common';\nimport { Context, ContextInit } from '../context/context.js';\nimport { DocumentManager } from '../entities/DocumentManager.js';\nimport { EntityStore } from '../entities/EntityStore.js';\nimport { FileManager } from '../files/FileManager.js';\nimport { deleteAllDatabases } from '../persistence/idb/util.js';\nimport { ExportedData } from '../persistence/interfaces.js';\nimport { importPersistence } from '../persistence/persistence.js';\nimport { CollectionQueries } from '../queries/CollectionQueries.js';\nimport { PublicQueryCacheAPI, QueryCache } from '../queries/QueryCache.js';\nimport { NoSync, ServerSync, Sync } from '../sync/Sync.js';\nimport { getLatestVersion } from '../utils/versions.js';\n\n// not actually used below, but helpful for internal code which\n// might rely on this stuff...\nexport type ClientWithCollections = Client & {\n\t[key: string]: CollectionQueries<any, any, any>;\n};\n\nexport class Client<Presence = any, Profile = any> extends EventSubscriber<{\n\t/**\n\t * Called when a change from a future version of the application has\n\t * been witnessed. These changes are not applied but it indicates\n\t * the app has been updated and a peer is using a newer version.\n\t * You should listen to this event and prompt the user to reload\n\t * their client, or reload it for them.\n\t *\n\t * This event may be called multiple times.\n\t */\n\tfutureSeen: () => void;\n\t/**\n\t * The server requested this replica reset its state\n\t * completely. This can happen when the replica has\n\t * been offline for too long and reconnects.\n\t */\n\tresetToServer: () => void;\n\t/**\n\t * These are errors that, as a developer, you should subscribe to\n\t * and prompt users to contact you for resolution. Usually these errors\n\t * indicate the client is in an unrecoverable state.\n\t */\n\tdeveloperError: (err: Error) => void;\n\t/**\n\t * Listen for operations as they are applied to the database.\n\t * Wouldn't recommend using this unless you know what you're doing.\n\t * It's a very hot code path...\n\t */\n\toperation: (operation: Operation) => void;\n\t/**\n\t * Emitted when storage rebases history. This should never actually affect application behavior\n\t * or stored data, but is useful for debugging and testing.\n\t */\n\trebase: () => void;\n\t/**\n\t * Emitted when a file is stored locally. Used for test coordination right now.\n\t */\n\tfileSaved: (fileData: FileData) => void;\n}> {\n\tprivate _entities: EntityStore;\n\tprivate _queryCache: QueryCache;\n\tprivate _documentManager: DocumentManager<any>;\n\tprivate _fileManager: FileManager;\n\tprivate context: Context;\n\n\treadonly collectionNames: string[];\n\n\tprivate _sync!: Sync<Presence, Profile>;\n\n\tconstructor(private contextInit: ContextInit) {\n\t\tsuper();\n\t\tthis.context = new Context(this.contextInit);\n\t\tthis.context.getClient = () => this;\n\n\t\tthis.collectionNames = Object.keys(this.context.schema.collections);\n\t\tthis._sync =\n\t\t\tthis.context.config.sync && !this.context.schema.wip\n\t\t\t\t? new ServerSync<Presence, Profile>(this.context.config.sync, {\n\t\t\t\t\t\tonData: this.addData,\n\t\t\t\t\t\tctx: this.context,\n\t\t\t\t\t})\n\t\t\t\t: new NoSync<Presence, Profile>(this.context);\n\t\tif (this.context.schema.wip && this.context.config.sync) {\n\t\t\tthis.context.log(\n\t\t\t\t'warn',\n\t\t\t\t'\u26A0\uFE0F\u26A0\uFE0F Sync is disabled for WIP schemas. Commit your schema changes to start syncing again. \u26A0\uFE0F\u26A0\uFE0F',\n\t\t\t);\n\t\t}\n\n\t\tthis._fileManager = new FileManager({\n\t\t\tsync: this.sync,\n\t\t\tcontext: this.context,\n\t\t});\n\t\tthis._entities = new EntityStore({\n\t\t\tctx: this.context,\n\t\t\tfiles: this._fileManager,\n\t\t});\n\t\t// note: query cache must be initialized after EntityStore,\n\t\t// since EntityStore needs to clear its cache before queries\n\t\t// refresh.\n\t\t// FIXME: make this less fragile\n\t\tthis._queryCache = new QueryCache({\n\t\t\tcontext: this.context,\n\t\t\tevictionTime: this.context.config.queries?.evictionTime,\n\t\t});\n\t\tthis._documentManager = new DocumentManager(this.schema, this._entities);\n\n\t\tconst notifyFutureSeen = debounce(() => {\n\t\t\tthis.emit('futureSeen');\n\t\t}, 300);\n\t\tthis.context.globalEvents.subscribe('futureSeen', notifyFutureSeen);\n\t\tthis.context.globalEvents.subscribe('resetToServer', () => {\n\t\t\tthis.emit('resetToServer');\n\t\t});\n\t\tthis.context.globalEvents.subscribe('operation', (operation) => {\n\t\t\tthis.emit('operation', operation);\n\t\t});\n\t\tthis.context.globalEvents.subscribe('rebase', () => {\n\t\t\tthis.emit('rebase');\n\t\t});\n\t\tthis.context.globalEvents.subscribe('fileSaved', (file) => {\n\t\t\tthis.emit('fileSaved', file);\n\t\t});\n\n\t\t// self-assign collection shortcuts. these are not typed\n\t\t// here but are typed in the generated code...\n\t\tfor (const [name, _collection] of Object.entries(\n\t\t\tthis.context.schema.collections,\n\t\t)) {\n\t\t\tconst collectionName = name;\n\t\t\t(this as any)[collectionName] = new CollectionQueries({\n\t\t\t\tcollection: collectionName,\n\t\t\t\tcache: this._queryCache,\n\t\t\t\tcontext: this.context,\n\t\t\t\tentities: this.entities,\n\t\t\t\tdocumentManager: this.documentManager,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate importingPromise = Promise.resolve();\n\tprivate addData = async (data: {\n\t\toperations: Operation[];\n\t\tbaselines?: DocumentBaseline[];\n\t\treset?: boolean;\n\t}) => {\n\t\tif (this.context.closing) {\n\t\t\tthis.context.log(\n\t\t\t\t'warn',\n\t\t\t\t'Client is closing; ignoring incoming sync data',\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\t// always wait for an ongoing import to complete before handling data.\n\t\tawait this.importingPromise;\n\n\t\ttry {\n\t\t\tconst schemaVersion = data.reset\n\t\t\t\t? getLatestVersion(data)\n\t\t\t\t: this.schema.version;\n\n\t\t\tif (schemaVersion < this.schema.version) {\n\t\t\t\t/**\n\t\t\t\t * Edge case: the server has an older version of the library\n\t\t\t\t * than the client schema, but it wants the client to reset.\n\t\t\t\t *\n\t\t\t\t * This happens when a truant or new client loads up newest client\n\t\t\t\t * code with a new schema version, but the last sync to the\n\t\t\t\t * server was from an old version. It's particularly a problem\n\t\t\t\t * if the new schema drops collections, since the IDB table for\n\t\t\t\t * that collection will no longer exist, so loading in old data\n\t\t\t\t * will result in an error.\n\t\t\t\t *\n\t\t\t\t * To handle this, we treat the reset data as if it were an import\n\t\t\t\t * of exported data. The import procedure handles older\n\t\t\t\t * schema versions by resetting the database to the imported\n\t\t\t\t * version, then migrating up to the current version.\n\t\t\t\t */\n\t\t\t\tthis.context.log(\n\t\t\t\t\t'warn',\n\t\t\t\t\t'Incoming reset sync data is from an old schema version',\n\t\t\t\t\tschemaVersion,\n\t\t\t\t\t`(current ${this.schema.version})`,\n\t\t\t\t);\n\t\t\t\t// run through the import flow to properly handle old versions\n\t\t\t\treturn await this.import({\n\t\t\t\t\tdata: {\n\t\t\t\t\t\toperations: data.operations,\n\t\t\t\t\t\tbaselines: data.baselines ?? [],\n\t\t\t\t\t\t// keep existing\n\t\t\t\t\t\tlocalReplica: undefined,\n\t\t\t\t\t\tschemaVersion,\n\t\t\t\t\t},\n\t\t\t\t\tfileData: [],\n\t\t\t\t\tfiles: [],\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\treturn await this._entities.addData(data);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthis.context.log(\n\t\t\t\t'critical',\n\t\t\t\t'Sync failed. To avoid data corruption, the client will now shut down.',\n\t\t\t\terr,\n\t\t\t);\n\t\t\tthis.emit(\n\t\t\t\t'developerError',\n\t\t\t\tnew VerdantError(\n\t\t\t\t\tVerdantError.Code.Unexpected,\n\t\t\t\t\terr as any,\n\t\t\t\t\t'Sync failed. To avoid data corruption, the client will now shut down.',\n\t\t\t\t),\n\t\t\t);\n\t\t\tawait this.close();\n\t\t\tthrow err;\n\t\t}\n\t};\n\n\tget schema() {\n\t\treturn this.context.schema;\n\t}\n\n\tget namespace() {\n\t\treturn this.context.namespace;\n\t}\n\n\tget undoHistory() {\n\t\treturn this.context.undoHistory;\n\t}\n\n\tget queries(): PublicQueryCacheAPI {\n\t\treturn this._queryCache;\n\t}\n\n\tget sync() {\n\t\treturn this._sync;\n\t}\n\n\tget entities() {\n\t\treturn this._entities;\n\t}\n\n\tget documentManager() {\n\t\treturn this._documentManager;\n\t}\n\n\tasync getReplicaId() {\n\t\tconst replica = await (await this.context.meta).getLocalReplica();\n\t\treturn replica.id;\n\t}\n\n\t/**\n\t * Batch multiple operations together to be executed in a single transaction.\n\t * The changes made will not be included in the same undo history step as\n\t * any other changes made outside of the batch. You can also disable undo\n\t * for your batch to omit changes from undo history.\n\t *\n\t * Provide a batch name to apply multiple changes to the same batch\n\t * across different invocations. Batches will automatically flush after\n\t * a short delay or if they reach a maximum size.\n\t */\n\tget batch() {\n\t\treturn this.entities.batch;\n\t}\n\n\tstats = async (): Promise<ClientStats> => {\n\t\tif (this.disposed) {\n\t\t\treturn {} as any;\n\t\t}\n\t\tconst collections = await (await this.context.documents).stats();\n\t\tconst meta = await (await this.context.meta).stats();\n\t\tconst storage =\n\t\t\ttypeof navigator !== 'undefined' &&\n\t\t\ttypeof navigator.storage !== 'undefined' &&\n\t\t\t'estimate' in navigator.storage\n\t\t\t\t? await navigator.storage.estimate()\n\t\t\t\t: undefined;\n\n\t\tconst files = await (await this.context.files).stats();\n\n\t\t// determine data:metadata ratio for total size of all collections vs metadata\n\t\tconst totalCollectionsSize = Object.values(collections).reduce(\n\t\t\t(acc, { size }) => acc + size,\n\t\t\t0,\n\t\t);\n\t\tconst totalMetaSize = meta.baselinesSize.size + meta.operationsSize.size;\n\t\tconst metaToDataRatio = totalMetaSize / totalCollectionsSize;\n\n\t\treturn {\n\t\t\tcollections,\n\t\t\tmeta,\n\t\t\tstorage,\n\t\t\ttotalMetaSize,\n\t\t\ttotalCollectionsSize,\n\t\t\tmetaToDataRatio,\n\t\t\tfiles,\n\t\t\tquotaUsage:\n\t\t\t\tstorage?.usage && storage?.quota\n\t\t\t\t\t? storage.usage / storage.quota\n\t\t\t\t\t: undefined,\n\t\t};\n\t};\n\n\tclose = async () => {\n\t\tthis.sync.ignoreIncoming();\n\t\tawait this._entities.flushAllBatches();\n\t\t// NOTE: this happens after flushing or else flushed data\n\t\t// won't be written to storage or synced.\n\t\tthis.context.closing = true;\n\t\tif (this.context.closeLock) {\n\t\t\tawait this.context.closeLock;\n\t\t}\n\t\tawait this.sync.stop();\n\t\tthis.sync.destroy();\n\t\t// this step does have the potential to flush\n\t\t// changes to storage, so don't close metadata db yet\n\t\tawait this._entities.destroy();\n\n\t\tthis.context.persistenceShutdownHandler.shutdown();\n\t\tthis.context.internalEvents.disable();\n\t\tthis.context.entityEvents.disable();\n\n\t\t// the idea here is to flush the microtask queue -\n\t\t// we may have queued tasks related to queries that\n\t\t// we want to settle before closing the databases\n\t\t// to avoid invalid state errors\n\t\tawait new Promise<void>((resolve) => {\n\t\t\tresolve();\n\t\t});\n\n\t\tthis.context.log?.('info', 'Client closed');\n\t};\n\n\t__dangerous__resetLocal = async () => {\n\t\tthis.sync.stop();\n\t\tawait deleteAllDatabases(this.namespace, this.context.environment);\n\t};\n\n\texport = async (\n\t\t{ downloadRemoteFiles }: { downloadRemoteFiles?: boolean } = {\n\t\t\tdownloadRemoteFiles: true,\n\t\t},\n\t): Promise<ExportedData> => {\n\t\tthis.context.log('info', 'Exporting data...');\n\t\tconst metaExport = await (await this.context.meta).export();\n\t\tconst { fileData, files } = await (\n\t\t\tawait this.context.files\n\t\t).export(downloadRemoteFiles);\n\t\treturn {\n\t\t\tdata: metaExport,\n\t\t\tfileData,\n\t\t\tfiles,\n\t\t};\n\t};\n\n\timport = async ({ data, fileData, files }: ExportedData) => {\n\t\t/**\n\t\t * Importing is a pretty involved procedure because of the possibility of\n\t\t * importing an export from an older version of the schema. We can't add\n\t\t * data from older schemas because the indexes may have changed or whole\n\t\t * collections may have been since deleted, leaving no corresponding IDB\n\t\t * tables.\n\t\t *\n\t\t * Since IDB doesn't allow us to go backwards, and we are resetting all\n\t\t * data anyways, the import procedure blows away the current queryable DB\n\t\t * and restarts from the imported schema version. It then migrates up\n\t\t * to the latest (current) version. These migrations are added to the imported\n\t\t * data to produce the final state.\n\t\t */\n\n\t\t// register importing promise to halt other data handling\n\t\tlet resolve = () => {};\n\t\tthis.importingPromise = new Promise<void>((res) => {\n\t\t\tresolve = res;\n\t\t});\n\n\t\tthis.context.log('info', 'Importing data...');\n\n\t\tawait importPersistence(this.context, { data, files, fileData });\n\n\t\t// finally... clear out memory cache of entities and\n\t\t// re-run all active queries.\n\t\t// this.entities.clearCache();\n\t\t// this._queryCache.forceRefreshAll();\n\n\t\t// ^ this is now done via the persistenceReset internal event.\n\n\t\tresolve();\n\t};\n\n\t/**\n\t * Export all data, then re-import it. This might resolve\n\t * some issues with the local database, but it should\n\t * only be done as a second-to-last resort. The last resort\n\t * would be __dangerous__resetLocal, which\n\t * clears all local data.\n\t *\n\t * Unlike __dangerous__resetLocal, this method allows local-only\n\t * clients to recover data, whereas __dangerous__resetLocal only\n\t * lets networked clients recover from the server.\n\t */\n\t__dangerous__hardReset = async () => {\n\t\tconst exportData = await this.export();\n\t\tawait this.import(exportData);\n\t};\n\n\t/**\n\t * Immediately runs the file deletion process. This is useful\n\t * for testing, mostly. Or if your client is long-lived, since\n\t * normally this cleanup only runs on startup.\n\t *\n\t * Note this still follows the file deletion heuristic configured\n\t * on the client. So if you clean up files 3 days after delete,\n\t * invoking this manually will not skip that 3 day waiting period.\n\t */\n\t__cleanupFilesImmediately = async () => {\n\t\treturn (await this.context.files).cleanupDeletedFiles();\n\t};\n\n\t/**\n\t * Manually triggers storage rebasing. Follows normal\n\t * rebasing rules. Rebases already happen automatically\n\t * during normal operation, so you probably don't need this.\n\t */\n\t__manualRebase = async () => {\n\t\t// not awaiting; relying on event below as this method only schedules.\n\t\t(await this.context.meta).manualRebase();\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tconst unsub = this.subscribe('rebase', () => {\n\t\t\t\tunsub();\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t};\n\n\t/**\n\t * WARNING: the internal functions of the persistence layer\n\t * are not guaranteed and cannot be relied upon for application\n\t * behavior. They are subject to change without notice.\n\t */\n\tget __persistence() {\n\t\treturn {\n\t\t\tmeta: this.context.meta,\n\t\t\tqueries: this.context.documents,\n\t\t\tfiles: this.context.files,\n\t\t};\n\t}\n\n\tget __persistenceReady() {\n\t\treturn this.context.waitForInitialization;\n\t}\n}\n\nexport interface ClientStats {\n\tcollections: Record<string, { count: number; size: number }>;\n\tmeta: {\n\t\tbaselinesSize: { count: number; size: number };\n\t\toperationsSize: { count: number; size: number };\n\t};\n\tfiles: {\n\t\tsize: { count: number; size: number };\n\t};\n\tstorage: StorageEstimate | undefined;\n\ttotalMetaSize: number;\n\ttotalCollectionsSize: number;\n\tmetaToDataRatio: number;\n\tquotaUsage: number | undefined;\n}\n", "import { authz } from '@verdant-web/common';\n\nexport const authorization = {\n\tprivate: authz.onlyMe(),\n\tpublic: undefined,\n};\n", "export function cliSync<Presence extends any = any>(\n\tlibraryId: string,\n\t{\n\t\tport = 3242,\n\t\tinitialPresence = {} as any,\n\t}: { port?: number; initialPresence?: Presence } = {},\n) {\n\tlet userId = localStorage.getItem('verdant-userId');\n\tif (!userId) {\n\t\tuserId = `user-${Math.random().toString(36).slice(2)}`;\n\t\tlocalStorage.setItem('verdant-userId', userId);\n\t}\n\treturn {\n\t\tdefaultProfile: { id: userId },\n\t\tinitialPresence,\n\t\tauthEndpoint: `http://localhost:${port}/auth/${libraryId}?userId=${userId}`,\n\t};\n}\n", "import cuid from 'cuid';\n\nexport function id(short?: boolean) {\n\tif (short) return cuid.slug();\n\treturn cuid();\n}\n", "import * as everything from './index.js';\n\n(window as any).Verdant = everything;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["require_object_hash", "__commonJSMin", "exports", "module", "e", "t", "r", "o", "i", "u", "s", "n", "a", "w", "b", "m", "c", "d", "h", "g", "y", "l", "f", "O", "H", "p", "j", "C", "v", "_", "E", "I", "A", "Y", "B", "F", "L", "U", "D", "x", "T", "M", "k", "N", "S", "require_pad", "__commonJSMin", "exports", "module", "num", "size", "s", "require_fingerprint_browser", "__commonJSMin", "exports", "module", "pad", "env", "globalCount", "mimeTypesLength", "clientId", "require_getRandomValue_browser", "__commonJSMin", "exports", "module", "getRandomValue", "crypto", "lim", "require_cuid", "__commonJSMin", "exports", "module", "fingerprint", "pad", "getRandomValue", "c", "blockSize", "base", "discreteValues", "randomBlock", "safeCounter", "cuid", "letter", "timestamp", "counter", "print", "random", "date", "stringToCheck", "stringLength", "tslib_es6_exports", "__export", "__addDisposableResource", "__assign", "__asyncDelegator", "__asyncGenerator", "__asyncValues", "__await", "__awaiter", "__classPrivateFieldGet", "__classPrivateFieldIn", "__classPrivateFieldSet", "__createBinding", "__decorate", "__disposeResources", "__esDecorate", "__exportStar", "__extends", "__generator", "__importDefault", "__importStar", "__makeTemplateObject", "__metadata", "__param", "__propKey", "__read", "__rest", "__runInitializers", "__setFunctionName", "__spread", "__spreadArray", "__spreadArrays", "__values", "tslib_es6_default", "d", "b", "extendStatics", "__", "s", "e", "t", "p", "i", "decorators", "target", "key", "desc", "c", "r", "paramIndex", "decorator", "ctor", "descriptorIn", "contextIn", "initializers", "extraInitializers", "accept", "f", "kind", "descriptor", "_", "done", "context", "result", "thisArg", "value", "useValue", "x", "name", "prefix", "metadataKey", "metadataValue", "_arguments", "P", "generator", "adopt", "resolve", "reject", "fulfilled", "step", "rejected", "body", "y", "g", "verb", "n", "v", "op", "m", "o", "ar", "error", "il", "k", "a", "j", "jl", "to", "from", "pack", "l", "q", "resume", "settle", "fulfill", "cooked", "raw", "mod", "__setModuleDefault", "receiver", "state", "env", "async", "dispose", "fail", "_SuppressedError", "next", "rec", "init_tslib_es6", "__esmMin", "k2", "suppressed", "message", "require_typed_event_interfaces", "__commonJSMin", "exports", "eventHandlerSafeInvoke", "handler", "sender", "args", "error", "exports", "eventHandlerSafeInvokeAsync", "invokeEventHandlers", "handlers", "options", "succeeded", "invokeEventHandlersAsync", "handlerPromises", "typed_event_functional_1", "DEFAULT_INVOCATION_OPTS", "TypedEvent", "handler", "sender", "args", "options", "handlerToRemove", "handlerIdx", "exports", "tslib_1", "exports", "FinalizationRegistryMissingError", "exports", "errors_1", "WeakHandlerHolder", "finalizer", "err", "eventSource", "handler", "handlerRef", "refToUse", "ref", "exports", "base_event_1", "weak_event_finalization_1", "typed_event_functional_1", "DEFAULT_INVOCATION_OPTS", "WeakEvent", "heldValue", "sender", "args", "options", "handlerRef", "dereferencedHandler", "succeeded", "error", "handlerPromises", "handler", "ref", "handlerIdx", "exports", "tslib_1", "exports", "tslib_1", "exports", "src_exports", "__export", "Client", "Entity", "EntityFile", "IdbPersistence", "ServerSync", "UndoHistory", "authorization", "cliSync", "createMigration", "debugLogger", "getEntityClient", "id", "makeLogger", "noLogger", "schema", "encode", "str", "decode", "authz", "userId", "ORIGINATOR_SUBJECT", "encoded", "parts", "rewriteAuthzOriginator", "data", "newSubject", "operations", "baselines", "op", "baseline", "Batcher", "flusher", "key", "batch", "userData", "items", "max", "timeout", "Batch", "startedAt", "needsSchedule", "VerdantErrorCode", "VerdantError", "code", "cause", "message", "status", "isVerdantErrorResponse", "body", "getRandomValues", "rnds8", "rng", "regex_default", "validate", "uuid", "regex_default", "validate_default", "byteToHex", "i", "stringify", "arr", "offset", "uuid", "validate_default", "stringify_default", "v4", "options", "buf", "offset", "rnds", "rng", "i", "stringify_default", "v4_default", "import_object_hash", "orderedReplacer", "k", "v", "ka", "kb", "stableStringify", "obj", "seen", "cyclicCount", "cloneDeep", "copyOids", "isObject", "oid", "maybeGetOid", "clone", "key", "value", "assignOid", "hashObject", "hash", "roughSizeOfObject", "object", "objectList", "stack", "bytes", "i", "assert", "condition", "message", "generateId", "length", "v4_default", "findLastIndex", "array", "predicate", "debounce", "fn", "wait", "timeout", "args", "context", "throttle", "lastTime", "trailingTimeout", "now", "safeStringify", "obj", "isFileRef", "value", "createFileRef", "id", "isFile", "value", "isFileData", "isObject", "isRef", "obj", "isObjectRef", "isFileRef", "compareRefs", "a", "b", "isObjectRef", "obj", "initialToPatches", "initial", "rootOid", "getNow", "createSubId", "patches", "options", "assignOid", "assignOidsToAllSubObjects", "normalized", "normalize", "key", "value", "op", "removeOid", "addAuthzToOp", "shallowInitialToPatches", "authz", "groupPatchesByOid", "grouped", "patch", "groupPatchesByRootOid", "root", "getOidRoot", "groupBaselinesByRootOid", "baselines", "listCheck", "maybeGetOid", "applyPatch", "base", "deletedRefs", "baseAsAny", "index", "spliceResult", "checkRef", "field", "isRef", "valueToRemove", "findLastIndex", "item", "compareRefs", "v", "isObject", "cloneDeep", "substituteRefsWithObjects", "base", "refs", "used", "i", "item", "dereference", "isObject", "isFileRef", "assert", "maybeGetOid", "key", "input", "isObjectRef", "resolved", "assignOid", "operationSupersedes", "op", "isSuperseded", "supersession", "pickValidOperationKeys", "operation", "SEGMENT_SEPARATOR", "RANDOM_SEPARATOR", "oidMap", "getOid", "obj", "oid", "maybeGetOid", "assert", "safeStringify", "isObject", "assignOid", "hasOid", "removeOid", "ensureCompatibleOid", "obj", "rootOid", "createSubId", "hasOid", "existingOid", "getOid", "areOidsRelated", "oid", "createSubOid", "assignOid", "SANITIZE_PLACEHOLDERS", "sanitizeFragment", "id", "unsanitizeFragment", "createOid", "collection", "documentId", "subId", "SEGMENT_SEPARATOR", "RANDOM_SEPARATOR", "root", "createOidSubId", "decomposeOid", "coreId", "others", "idOrLegacyPathId", "random", "assignOidsToAllSubObjects", "obj", "createSubId", "rootOid", "getOid", "item", "i", "isObject", "isRef", "ensureCompatibleOid", "key", "removeOidsFromAllSubObjects", "removeOid", "createOidSubId", "v4_default", "createRef", "oid", "normalize", "refs", "copy", "assignOid", "value", "isObjectRef", "isFileRef", "itemOid", "getOidRoot", "oid", "RANDOM_SEPARATOR", "getOidSubIdRange", "root", "lastSubId", "createSubOid", "areOidsRelated", "oidA", "oidB", "getOidRoot", "isRootOid", "oid", "RANDOM_SEPARATOR", "LEGACY_OID_KEY", "OID_KEY", "maybeGetOidProperty", "obj", "isObject", "removeOidProperty", "copyOidFromPropertyToSystem", "oid", "assignOid", "removeOidPropertiesFromAllSubObjects", "key", "convertLegacyOid", "oid", "collection", "id", "subId", "decomposeOid", "createOid", "MATCH_LEGACY_OID_JSON_STRING", "replaceLegacyOidsInJsonString", "string", "match", "legacyOid", "replaceLegacyOidsInObject", "obj", "getLegacyDotOidSubIdRange", "root", "getOidRoot", "isOidKey", "key", "OID_KEY", "LEGACY_OID_KEY", "PatchCreator", "getNow", "createSubId", "value", "isObject", "isRef", "from", "to", "options", "diffToPatches", "obj", "oid", "authz", "shallow", "shallowInitialToPatches", "initialToPatches", "key", "itemOid", "createSubOid", "createRef", "index", "assert", "values", "operations", "refs", "subOid", "only", "count", "fromIndex", "toIndex", "oids", "areTheSameIdentity", "a", "b", "isRef", "compareRefs", "aOid", "maybeGetOid", "bOid", "enforceAssignedOid", "parentOid", "newObject", "existingObjectOid", "ctx", "isDiffableObject", "oid", "assignOid", "areOidsRelated", "cloneDeep", "val", "isObject", "diffToPatches", "from", "to", "getNow", "createSubId", "_", "options", "_a", "PatchCreator", "diff", "diffLists", "VerdantError", "diffObjects", "getOid", "fromCopy", "oidsInFrom", "i", "value", "oldValue", "noGaps", "movedItems", "overwrittenItems", "itemOid", "isEndOfList", "createRef", "fromOid", "isPreviousItemStillThere", "isNextItemStillThere", "deleteWithSubObjects", "overwrittenOid", "item", "x", "oldKeys", "key", "isOidKey", "root", "EventSubscriber", "_onAllUnsubscribed", "event", "_a", "acc", "count", "callback", "key", "generateId", "subscribers", "args", "c", "events", "COMPOUND_INDEX_SEPARATOR", "COMPOUND_INDEX_LOWER_BOUND_SEPARATOR", "COMPOUND_INDEX_UPPER_BOUND_SEPARATOR", "createCompoundIndexValue", "fields", "value", "expandArrayIndex", "createUpperBoundIndexValue", "createLowerBoundIndexValue", "field", "newValue", "previousValue", "fieldValue", "item", "isDirectSynthetic", "index", "computeSynthetics", "schema", "obj", "result", "name", "property", "sanitizeIndexValue", "computeCompoundIndices", "doc", "acc", "indexKey", "key", "computeIndexedFields", "getIndexValues", "basicIndexes", "NULL_INDEX_VALUE", "sanitizeIndexValue", "value", "memoByKeys", "fn", "getKeys", "cachedKeys", "cachedResult", "args", "keys", "key", "i", "emptySchema", "getIndexes", "collection", "key", "index", "indexType", "assert", "multiEntry", "isMultiValueIndex", "createMigration", "maybeOldSchema", "maybeNewSchemaOrProcedure", "maybeProcedure", "isProcedureSecondArgument", "oldSchema", "emptySchema", "newSchema", "procedure", "assert", "changedCollections", "addedCollections", "removedCollections", "addedIndexes", "removedIndexes", "autoMigratedCollections", "autoMigration", "getMigrationInfo", "engine", "migratedCollections", "collection", "strategy", "auto", "wrapped", "val", "baseValue", "assignOid", "getOid", "result", "validationError", "validateEntity", "name", "unmigrated", "key", "stableStringify", "oldFields", "newFields", "isRequired", "changed", "oldIndexes", "getIndexes", "newIndexes", "added", "index", "i", "removed", "collectionName", "addFieldDefaults", "removeExtraProperties", "initialInternalPresence", "ReplicaType", "import_cuid", "objectField", "args", "properties", "fields", "resolvedArgs", "__rest", "props", "replaceObjectFields", "object", "arrayField", "replaceArrayItems", "array", "items", "stringField", "numberField", "booleanField", "anyField", "mapField", "replaceMapValues", "map", "values", "fileField", "idField", "cuid", "import_cuid", "isMatchIndexFilter", "filter", "isRangeIndexFilter", "isCompoundIndexFilter", "isStartsWithIndexFilter", "isSortIndexFilter", "isMultiValueIndex", "collectionSchema", "indexName", "compound", "_a", "fieldOrIndexName", "index", "_b", "isMultiEntryIndexType", "field", "type", "isNullable", "field", "hasDefault", "isRequired", "addFieldDefaults", "collection", "value", "key", "field", "defaultValue", "getFieldDefault", "isNullable", "traverseCollectionFieldsAndApplyDefaults", "subField", "item", "OID_KEY", "LEGACY_OID_KEY", "val", "cloned", "property", "removeExtraProperties", "fieldValue", "traverseCollectionFieldsAndRemoveExtraProperties", "isObject", "isPrimitive", "fieldSchema", "validateEntity", "schema", "entity", "key", "value", "OID_KEY", "err", "validateEntityField", "field", "fieldPath", "depth", "requireDefaults", "expectRefs", "hasPassedFirstLevel", "actuallyExpectRefs", "isNullable", "hasDefault", "formatField", "isObjectRef", "safeStringify", "isObject", "subField", "error", "item", "isFileRef", "isFile", "isFileData", "constrainEntity", "constrained", "constrainEntityField", "validationProblem", "getChildFieldSchema", "schema", "key", "_a", "collection", "_a", "synthetics", "indexes", "input", "__rest", "finalIndexes", "key", "field", "schema", "fields", "cuid", "import_cuid", "VERSION_BLOCK_LENGTH", "ENCODING_NUMBER_RADIX", "encodeVersion", "version", "OLD_encodeVersion", "HybridLogicalClockTimestampProvider", "generateNodeId", "version", "getHlcNow", "OLD_encodeVersion", "OLD_serializeHlcTimestamp", "remoteTimestamp", "hlcString", "VERSION_BLOCK_LENGTH", "updateFromRemote", "deserializeHlcTimestamp", "raw", "encodeVersion", "serializeHlcTimestamp", "getWallClockTime", "ClockDriftError", "args", "OverflowError", "COUNTER_BLOCK_LENGTH", "NODE_BLOCK_LENGTH", "MAX_CLOCK_DRIFT", "TIME_BLOCK_LENGTH", "cuid", "ts", "dateString", "ENCODING_NUMBER_RADIX", "counter", "node", "prev", "wallTime", "newWallTime", "newCounter", "local", "remote", "newTime", "maxCounter", "clock", "time", "counterNum", "OLD_serializeHlcTimestamp", "ts", "dateString", "counter", "node", "getTimestampSchemaVersion", "timestamp", "VERSION_BLOCK_LENGTH", "compareTimestampSchemaVersions", "a", "b", "getWallClockTime", "deserializeHlcTimestamp", "getUndoOperations", "oid", "initial", "operations", "getNow", "getSubId", "authz", "patchCreator", "PatchCreator", "state", "cloneDeep", "undoOperations", "operation", "undo", "getUndoOperation", "applyPatch", "data", "_a", "_b", "findItemRefIndex", "index", "indexesOfValue", "list", "item", "from", "dir", "method", "isRef", "i", "idx", "FakeWeakRef", "value", "UndoHistory", "EventSubscriber", "next", "redo", "undo", "undoPoint", "redoPoint", "noLogger", "makeLogger", "prefix", "level", "args", "debugLogger", "Disposable", "dispose", "err", "disposable", "globalIDB", "isAbortError", "err", "storeRequestPromise", "request", "resolve", "reject", "getSizeOfObjectStore", "database", "storeName", "resolve", "reject", "tx", "cursorReq", "count", "size", "e", "cursor", "roughSizeOfObject", "isAbortError", "getAllFromObjectStores", "db", "stores", "transaction", "promises", "store", "objectStore", "storeRequestPromise", "closeDatabase", "resolve", "deleteAllDatabases", "namespace", "environment", "req1", "req2", "reject", "deleteDatabase", "name", "indexedDB", "getAllDatabaseNamesAndVersions", "createAbortableTransaction", "storeNames", "mode", "abortSignal", "log", "tx", "abort", "e", "err", "req", "_", "isTransactionAborted", "overwriteDatabase", "from", "toName", "ctx", "d", "to", "openRequest", "original", "upgradeTx", "storeName", "originalObjectStore", "originalStore", "index", "originalIndex", "records", "writeTx", "i", "record", "ev", "openDatabase", "expectedVersion", "event", "getMetadataDbName", "getDocumentDbName", "getNamespaceFromDatabaseInfo", "info", "IdbService", "Disposable", "db", "ctx", "storeNames", "opts", "tx", "createAbortableTransaction", "err", "storeName", "getRequest", "isTransactionAborted", "store", "request", "storeRequestPromise", "getRequests", "requests", "iterator", "req", "resolve", "reject", "cursor", "isAbortError", "transaction", "ev", "abortController", "IdbPersistenceFileDb", "IdbService", "file", "buffer", "fileToArrayBuffer", "store", "id", "current", "fileId", "raw", "since", "tx", "filtered", "iterator", "value", "options", "files", "getAllFromObjectStores", "getSizeOfObjectStore", "ctx", "response", "arrayBufferToBlob", "transaction", "type", "name", "resolve", "reject", "reader", "IdbMetadataDb", "IdbService", "db", "ctx", "opts", "procedure", "tx", "result", "store", "ack", "data", "e", "rootOid", "iterator", "root", "getOidRoot", "start", "end", "getOidSubIdRange", "dotStart", "dotEnd", "getLegacyDotOidSubIdRange", "collection", "oid", "baselines", "writeOpts", "b", "index", "createLowerBoundIndexValue", "createCompoundIndexValue", "createUpperBoundIndexValue", "range", "op", "ops", "affected", "clearReplica", "transaction", "getSizeOfObjectStore", "clear", "localInfo", "closeDatabase", "migrations", "version1", "version2", "version3", "version4", "version5", "version6", "CURRENT_METADATA_VERSION", "openMetadataDatabase", "indexedDB", "namespace", "log", "resolve", "reject", "request", "getMetadataDbName", "wasInitialized", "event", "db", "tx", "toRun", "migration", "baselinesStore", "operationsStore", "infoStore", "operations", "cursorReq", "cursor", "isLocal_timestamp", "documentOid_timestamp", "value", "files", "converted", "replaceLegacyOidsInObject", "baselines", "matchIndexToIdbKeyRange", "filter", "sanitizeIndexValue", "sortIndexToIdbKeyRange", "rangeIndexToIdbKeyRange", "lower", "upper", "compoundIndexToIdbKeyRange", "schema", "collection", "indexDefinition", "assert", "matchedKeys", "a", "b", "key", "matchedValues", "createCompoundIndexValue", "createLowerBoundIndexValue", "createUpperBoundIndexValue", "startsWithIndexToIdbKeyRange", "getRange", "index", "isRangeIndexFilter", "isMatchIndexFilter", "isSortIndexFilter", "isStartsWithIndexFilter", "IdbDocumentDb", "IdbService", "db", "context", "collectionNames", "collections", "name", "size", "getSizeOfObjectStore", "opts", "result", "store", "source", "direction", "range", "getRange", "createOid", "collection", "index", "offset", "limit", "tx", "isTransactionAborted", "request", "hasNextPage", "resolve", "reject", "hasDoneOffset", "visited", "results", "cursor", "isAbortError", "entities", "optsAndInfo", "options", "e", "snapshot", "err", "failures", "r", "names", "oid", "doc", "transaction", "id", "decomposeOid", "schema", "indexes", "getIndexValues", "closeDatabase", "upgradeDatabase", "indexedDb", "namespace", "version", "upgrader", "log", "openAndUpgrade", "resolve", "reject", "request", "getDocumentDbName", "wasUpgraded", "event", "transaction", "closeDatabase", "openDatabase", "indexedDB", "globalIDB", "db", "IdbPersistence", "indexedDB", "dbs", "getNamespaceFromDatabaseInfo", "n", "namespace", "databaseName", "getDocumentDbName", "existingDb", "info", "deleteDatabase", "getMetadataDbName", "IdbPersistenceNamespace", "from", "to", "ctx", "fromCtx", "toCtx", "fromMetaDb", "openMetadataDatabase", "fromDocumentsDb", "openDatabase", "overwriteDatabase", "closeDatabase", "db", "IdbMetadataDb", "IdbDocumentDb", "migration", "upgradeDatabase", "transaction", "newCollection", "collection", "store", "newIndex", "oldIndex", "removedCollection", "IdbPersistenceFileDb", "ShutdownHandler", "log", "handler", "getWipNamespace", "namespace", "schema", "hashObject", "getMigrationMutations", "migration", "newOids", "ctx", "meta", "acc", "collectionName", "doc", "options", "addFieldDefaults", "primaryKey", "oid", "createOid", "id", "rootOid", "getMigrationQueries", "context", "documents", "filter", "oids", "getMigrationEngine", "ns", "migrationContext", "getInitialMigrationEngine", "queries", "mutations", "deleteCollection", "collection", "awaitables", "strategy", "docs", "getOid", "assert", "authz", "original", "cloneDeep", "newValue", "removeOidPropertiesFromAllSubObjects", "assignOidsToAllSubObjects", "patches", "diffToPatches", "finalizeMigration", "ctx", "documents", "migration", "meta", "engine", "docsWithUnappliedMigrations", "getDocsWithUnappliedMigrations", "collection", "oids", "oid", "decomposeOid", "views", "snap", "e", "s", "snapshot", "currentVersion", "_", "unappliedOperations", "op", "getOidRoot", "getMigrationPath", "currentVersion", "targetVersion", "migrations", "path", "getNextPathStep", "VerdantError", "fromHere", "m", "a", "b", "next", "nextPath", "migrate", "context", "version", "meta", "ns", "acquireLock", "currentVersion", "toRun", "getMigrationPath", "m", "runMigrations", "namespace", "procedure", "migration", "migrationContext", "ShutdownHandler", "engine", "getMigrationEngine", "err", "upgradedDocuments", "finalizeMigration", "col", "i", "PersistenceFiles", "db", "context", "since", "file", "options", "blob", "originalFileName", "id", "downloadRemote", "storedFiles", "storedFile", "err", "fileData", "files", "fileExport", "asFile", "fileToIdMap", "importedFiles", "name", "retries", "maxRetries", "resolve", "reject", "count", "skipCount", "deletable", "fileRefs", "fileRef", "import_cuid", "MessageCreator", "db", "meta", "ctx", "init", "localInfo", "pickValidOperationKeys", "since", "localReplicaInfo", "provideChangesSince", "operations", "affectedDocs", "tx", "patch", "getOidRoot", "baselines", "b", "data", "nonce", "reason", "PersistenceRebaser", "db", "meta", "ctx", "globalAckTimestamp", "transaction", "toRebase", "lastTimestamp", "operationCount", "patch", "newBaselines", "oid", "timestamp", "upTo", "baseline", "current", "operationsApplied", "authz", "deletedRefs", "applyPatch", "assignOid", "newBaseline", "fileRefs", "isFileRef", "PersistenceMetadata", "db", "ctx", "operations", "options", "affectedDocumentOids", "op", "operation", "message", "baselines", "affectedOidSet", "baseline", "getOidRoot", "rootOid", "oids", "documentOid", "assert", "transaction", "patch", "authz", "ops", "oid", "collection", "b", "objectMap", "assignOid", "obj", "newObj", "applyPatch", "root", "substituteRefsWithObjects", "data", "timestamp", "ack", "lookup", "replicaInfo", "cuid", "opts", "original", "localReplica", "ackInfo", "localReplicaInfo", "PersistenceRebaser", "MessageCreator", "PersistenceDocuments", "db", "ctx", "entities", "options", "currentCollectionSet", "collections", "filteredEntities", "entity", "collection", "decomposeOid", "initializePersistence", "ctx", "initialSchema", "getWipNamespace", "currentVersion", "currentSchema", "s", "VerdantError", "namespace", "meta", "PersistenceMetadata", "files", "PersistenceFiles", "migrate", "documents", "PersistenceDocuments", "namespaces", "importPersistence", "exportedData", "exportedSchema", "importedNamespace", "importedContext", "ShutdownHandler", "importedMeta", "affectedOids", "baseline", "getOidRoot", "operation", "toSave", "oid", "snapshot", "upgradedContext", "stats", "Time", "base", "version", "run", "defaultBrowserEnvironment", "Context", "_Context", "init", "initPersistence", "value", "FakeWeakRef", "VerdantError", "initializePersistence", "Time", "HybridLogicalClockTimestampProvider", "noLogger", "debugLogger", "UndoHistory", "EventSubscriber", "PatchCreator", "ShutdownHandler", "IdbPersistence", "options", "DocumentManager", "schema", "entities", "collection", "init", "primaryKeyName", "primaryKey", "assert", "createOid", "collectionName", "addFieldDefaults", "constrainEntity", "options", "widenedOptions", "defaulted", "validated", "oid", "collectionSchema", "ids", "entity", "isRootOid", "snapshot", "final", "import_weak_event", "import_cuid", "createFileData", "file", "cuid", "processValueFiles", "value", "onFileIdentified", "isFile", "data", "createFileRef", "isFileData", "cloned", "i", "key", "UPDATE", "MARK_FAILED", "CHILD_FILE_CHANGED", "_a", "_b", "EntityFile", "EventSubscriber", "id", "downloadRemote", "ctx", "parent", "fileData", "reason", "data", "EntityCache", "initial", "ctx", "init", "cached", "entity", "Entity", "oid", "derefed", "entityFieldSubscriber", "entity", "field", "subscriber", "valueHolder", "handler", "info", "newValue", "PRIVATE_ENTITY_CONTEXT_KEY", "_a", "Entity", "_Entity", "EventSubscriber", "oid", "schema", "childCache", "parent", "ctx", "metadataFamily", "readonlyKeys", "files", "storeEvents", "deleteSelf", "fieldPath", "_store", "data", "child", "childView", "key", "fieldSchema", "getChildFieldSchema", "assert", "memoByKeys", "validateEntityField", "mapper", "view", "mapped", "value", "EntityFile", "assignOid", "acc", "i", "isRef", "operations", "op", "changes", "change", "snapshot", "unprunedSnapshot", "ev", "other", "target", "file", "event", "callback", "entityFieldSubscriber", "assertNotSymbol", "isFileRef", "isNullable", "hasDefault", "getFieldDefault", "childEntity", "pruneDiff", "isPrimitive", "defaultValue", "prunedFieldOid", "createSubOid", "createRef", "init", "existing", "isFile", "cloneDeep", "traverseCollectionFieldsAndApplyDefaults", "validationError", "processValueFiles", "property", "item", "createFileRef", "itemOid", "maybeGetOid", "options", "assertNumber", "deleteMode", "merge", "replaceSubObjects", "preserveUndefined", "dangerouslyDisableMerge", "field", "index", "from", "to", "itemRef", "compareRefs", "initialValue", "predicate", "type", "operation", "EntityCache", "rawView", "isObject", "newView", "keys", "isObjectRef", "latest", "childTimestamp", "CHILD_FILE_CHANGED", "length", "getEntityClient", "entity", "EntityMetadata", "oid", "ctx", "confirmedOperations", "pendingOperations", "baseline", "omitPending", "base", "cloneDeep", "baselineTimestamp", "authz", "confirmedResult", "ephemeralResult", "pendingResult", "assignOid", "fromOlderVersion", "compareTimestampSchemaVersions", "empty", "updatedAtTimestamp", "updatedAt", "getWallClockTime", "operations", "totalAdded", "op", "index", "pendingPrior", "operation", "old", "deleted", "latestTimestamp", "after", "futureSeen", "now", "applyPatch", "err", "assert", "EntityFamilyMetadata", "onPendingOperations", "rootOid", "baselines", "isLocal", "changes", "areOidsRelated", "ops", "ent", "ephemeralCopy", "oids", "DEFAULT_BATCH_KEY", "OperationBatcher", "batchTimeout", "ctx", "entities", "operations", "batchKey", "meta", "committed", "supersessions", "i", "op", "existingSupersession", "isSuperseded", "supersession", "operationSupersedes", "undo", "undoable", "batchName", "generateId", "max", "timeout", "internalBatch", "externalApi", "fn", "data", "inverseOps", "redo", "ops", "source", "grouped", "groupPatchesByOid", "getNow", "oid", "patches", "viewData", "getOidRoot", "inverse", "getUndoOperations", "Batcher", "EntityStore", "Disposable", "ctx", "files", "oid", "data", "baselines", "operations", "allDocumentOids", "b", "getOidRoot", "o", "baselinesGroupedByOid", "groupBaselinesByRootOid", "operationsGroupedByOid", "groupPatchesByRootOid", "groupedOperations", "groupPatchesByOid", "event", "hydrationPromise", "abortOptions", "entities", "err", "opts", "isRootOid", "cached", "entity", "pendingPromise", "initial", "undoable", "access", "collection", "decomposeOid", "removeOidsFromAllSubObjects", "fileRefs", "processed", "processValueFiles", "assignOid", "schema", "VerdantError", "file", "oids", "options", "assert", "deletes", "op", "collectionName", "readonlyKeys", "metadataFamily", "EntityFamilyMetadata", "Entity", "operation", "root", "OperationBatcher", "FileManager", "Disposable", "sync", "context", "file", "parent", "entityFile", "EntityFile", "UPDATE", "processedFile", "id", "options", "fileData", "unsub", "online", "result", "copyWithUrl", "MARK_FAILED", "err", "data", "existsFilter", "x", "filterResultSet", "results", "Entity", "areIndexesEqual", "a", "b", "hashObject", "ON_ALL_UNSUBSCRIBED", "UPDATE", "_a", "BaseQuery", "Disposable", "initial", "context", "collection", "key", "shouldUpdate", "value", "filtered", "filterResultSet", "changed", "v", "i", "entity", "Entity", "startTime", "err", "endTime", "duration", "handler", "EventSubscriber", "event", "shouldUpdateFn", "collections", "eventOrCallback", "callback", "GetQuery", "BaseQuery", "id", "hydrate", "rest", "value", "createOid", "_a", "FindOneQuery", "BaseQuery", "index", "hydrate", "rest", "oid", "areIndexesEqual", "UPDATE", "_a", "FindPageQuery", "BaseQuery", "index", "hydrate", "pageSize", "page", "rest", "result", "hasNextPage", "areIndexesEqual", "UPDATE", "_a", "FindInfiniteQuery", "BaseQuery", "hydrate", "pageSize", "index", "rest", "result", "hasNextPage", "areIndexesEqual", "UPDATE", "_a", "FindAllQuery", "BaseQuery", "index", "hydrate", "rest", "oids", "areIndexesEqual", "UPDATE", "CollectionQueries", "collection", "cache", "entities", "context", "documentManager", "index", "hashObject", "id", "key", "GetQuery", "providedKey", "FindOneQuery", "existing", "UPDATE", "FindAllQuery", "pageSize", "page", "FindPageQuery", "FindInfiniteQuery", "QueryCache", "Disposable", "evictionTime", "context", "query", "q", "key", "value", "ON_ALL_UNSUBSCRIBED", "create", "update", "existing", "cached", "attemptToRegisterBackgroundSync", "status", "registration", "error", "FileSync", "Disposable", "endpointProvider", "ctx", "data", "e", "retries", "file", "fileEndpoint", "token", "formData", "response", "responseText", "resolve", "id", "HANDLE_MESSAGE", "_a", "PresenceManager", "EventSubscriber", "initialPresence", "updateBatchTimeout", "defaultProfile", "ctx", "localReplicaInfo", "userInfo", "message", "peersChanged", "selfChanged", "peerIdsSet", "id", "lastPresence", "presence", "presenceUpdates", "data", "update", "viewId", "fieldId", "timestamp", "peer", "expirationPeriod", "initialInternalPresence", "meta", "info", "Batcher", "everyone", "Heartbeat", "EventSubscriber", "interval", "deadlineLength", "restartOnTabFocus", "immediate", "PushPullSync", "EventSubscriber", "endpointProvider", "presence", "interval", "ctx", "messages", "host", "token", "response", "json", "handlePromise", "isVerdantErrorResponse", "VerdantErrorCode", "error", "message", "throttle", "Heartbeat", "InvalidCharacterError", "message", "this", "prototype", "Error", "name", "r", "window", "atob", "bind", "input", "str", "String", "replace", "length", "bs", "buffer", "bc", "idx", "output", "charAt", "fromCharCode", "indexOf", "t", "decodeURIComponent", "m", "p", "code", "charCodeAt", "toString", "toUpperCase", "err", "InvalidTokenError", "o", "token", "options", "pos", "header", "JSON", "parse", "base64_url_decode", "split", "e", "jwt_decode_esm_default", "ServerSyncEndpointProvider", "config", "ctx", "result", "fetchImpl", "res", "assert", "decoded", "jwt_decode_esm_default", "url", "httpEndpoint", "websocketEndpoint", "fileEndpoint", "fileUrl", "ReplicaType", "BackoffScheduler", "EventSubscriber", "backoff", "Backoff", "initial", "max", "factor", "WebSocketSync", "EventSubscriber", "endpointProvider", "ctx", "presence", "Heartbeat", "BackoffScheduler", "Backoff", "msg", "online", "meta", "event", "message", "endpoint", "WEBSOCKET_OPEN", "reason", "NoSync", "EventSubscriber", "ctx", "PresenceManager", "ServerSync", "authEndpoint", "fetchAuth", "initialPresence", "automaticTransportSelection", "autoStart", "initialTransport", "pullInterval", "presenceUpdateBatchTimeout", "defaultProfile", "useBroadcastChannel", "onOutgoingMessage", "EXPERIMENTAL_backgroundSync", "onData", "event", "message", "source", "op", "HANDLE_MESSAGE", "online", "unsyncedFiles", "results", "file", "r", "data", "transport", "newSync", "interval", "userId", "VerdantError", "rewriteAuthzOriginator", "info", "id", "timeout", "resolve", "reject", "timeoutHandle", "unsubscribe", "ServerSyncEndpointProvider", "WebSocketSync", "PushPullSync", "FileSync", "decideIfUpgrade", "switchoverTimeout", "shouldUpgrade", "attemptToRegisterBackgroundSync", "ReplicaType", "getLatestVersion", "data", "op", "b", "v", "ts", "tsVersion", "getTimestampSchemaVersion", "Client", "EventSubscriber", "contextInit", "data", "schemaVersion", "getLatestVersion", "err", "VerdantError", "collections", "meta", "storage", "files", "totalCollectionsSize", "acc", "size", "totalMetaSize", "metaToDataRatio", "resolve", "deleteAllDatabases", "downloadRemoteFiles", "metaExport", "fileData", "res", "importPersistence", "exportData", "unsub", "Context", "ServerSync", "NoSync", "FileManager", "EntityStore", "QueryCache", "DocumentManager", "notifyFutureSeen", "debounce", "operation", "file", "name", "_collection", "collectionName", "CollectionQueries", "authorization", "authz", "cliSync", "libraryId", "port", "initialPresence", "userId", "import_cuid", "id", "short", "cuid", "src_exports"]
|
|
7
7
|
}
|