@event-driven-io/emmett-postgresql 0.16.0 → 0.17.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/{chunk-NBTN5MZ6.js → chunk-5NYGSL2B.js} +3 -3
- package/dist/{chunk-PCRD6RK2.mjs → chunk-6Z7FIKB6.mjs} +2 -2
- package/dist/{chunk-WQQC2IS2.js → chunk-HFIQYR5E.js} +2 -2
- package/dist/chunk-JPTXK5ZT.mjs +2 -0
- package/dist/chunk-JPTXK5ZT.mjs.map +1 -0
- package/dist/{chunk-HS4KMVAP.mjs → chunk-NZWWNOXH.mjs} +2 -2
- package/dist/{chunk-HIX4PKIP.mjs → chunk-PT4NEEE4.mjs} +1 -1
- package/dist/{chunk-HIX4PKIP.mjs.map → chunk-PT4NEEE4.mjs.map} +1 -1
- package/dist/{chunk-6FBMFEVK.js → chunk-QB7BC56W.js} +1 -1
- package/dist/{chunk-6FBMFEVK.js.map → chunk-QB7BC56W.js.map} +1 -1
- package/dist/{chunk-DUXB3PBP.js → chunk-R5KGCWKQ.js} +4 -4
- package/dist/chunk-R5KGCWKQ.js.map +1 -0
- package/dist/{chunk-ST3FNDJ5.mjs → chunk-SIRCKLWA.mjs} +3 -3
- package/dist/chunk-SIRCKLWA.mjs.map +1 -0
- package/dist/chunk-UMWNWQRR.js +2 -0
- package/dist/chunk-UMWNWQRR.js.map +1 -0
- package/dist/chunk-WDTQXX5U.js +2 -0
- package/dist/chunk-WDTQXX5U.js.map +1 -0
- package/dist/chunk-XQJRZ4PO.mjs +2 -0
- package/dist/{chunk-J3JL23C4.mjs.map → chunk-XQJRZ4PO.mjs.map} +1 -1
- package/dist/eventStore/index.d.mts +1 -1
- package/dist/eventStore/index.d.ts +1 -1
- package/dist/eventStore/index.js +1 -1
- package/dist/eventStore/index.mjs +1 -1
- package/dist/eventStore/postgreSQLEventStore.d.mts +1 -1
- package/dist/eventStore/postgreSQLEventStore.d.ts +1 -1
- package/dist/eventStore/postgreSQLEventStore.js +1 -1
- package/dist/eventStore/postgreSQLEventStore.mjs +1 -1
- package/dist/eventStore/projections/index.d.mts +1 -1
- package/dist/eventStore/projections/index.d.ts +1 -1
- package/dist/eventStore/projections/index.js +1 -1
- package/dist/eventStore/projections/index.mjs +1 -1
- package/dist/eventStore/projections/pongo/index.d.mts +1 -1
- package/dist/eventStore/projections/pongo/index.d.ts +1 -1
- package/dist/eventStore/projections/pongo/index.js +1 -1
- package/dist/eventStore/projections/pongo/index.mjs +1 -1
- package/dist/eventStore/projections/pongo/pongoProjectionSpec.d.mts +1 -1
- package/dist/eventStore/projections/pongo/pongoProjectionSpec.d.ts +1 -1
- package/dist/eventStore/projections/pongo/pongoProjectionSpec.js +1 -1
- package/dist/eventStore/projections/pongo/pongoProjectionSpec.mjs +1 -1
- package/dist/eventStore/projections/pongo/projections.d.mts +1 -1
- package/dist/eventStore/projections/pongo/projections.d.ts +1 -1
- package/dist/eventStore/projections/pongo/projections.js +1 -1
- package/dist/eventStore/projections/pongo/projections.mjs +1 -1
- package/dist/eventStore/projections/postgresProjectionSpec.d.mts +1 -1
- package/dist/eventStore/projections/postgresProjectionSpec.d.ts +1 -1
- package/dist/eventStore/projections/postgresProjectionSpec.js +1 -1
- package/dist/eventStore/projections/postgresProjectionSpec.mjs +1 -1
- package/dist/eventStore/schema/appendToStream.d.mts +3 -1
- package/dist/eventStore/schema/appendToStream.d.ts +3 -1
- package/dist/eventStore/schema/appendToStream.js +1 -1
- package/dist/eventStore/schema/appendToStream.mjs +1 -1
- package/dist/eventStore/schema/index.js +1 -1
- package/dist/eventStore/schema/index.mjs +1 -1
- package/dist/eventStore/schema/readStream.js +1 -1
- package/dist/eventStore/schema/readStream.mjs +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/postgreSQLEventStore-BDzOzx7q.d.mts +268 -0
- package/dist/postgreSQLEventStore-BDzOzx7q.d.ts +268 -0
- package/package.json +2 -2
- package/dist/chunk-DUXB3PBP.js.map +0 -1
- package/dist/chunk-J3JL23C4.mjs +0 -2
- package/dist/chunk-JQ2VF3NG.js +0 -2
- package/dist/chunk-JQ2VF3NG.js.map +0 -1
- package/dist/chunk-KZTZL7GV.js +0 -2
- package/dist/chunk-KZTZL7GV.js.map +0 -1
- package/dist/chunk-QNOJWKPZ.mjs +0 -2
- package/dist/chunk-QNOJWKPZ.mjs.map +0 -1
- package/dist/chunk-ST3FNDJ5.mjs.map +0 -1
- package/dist/postgreSQLEventStore-loGROgA0.d.mts +0 -159
- package/dist/postgreSQLEventStore-loGROgA0.d.ts +0 -159
- /package/dist/{chunk-NBTN5MZ6.js.map → chunk-5NYGSL2B.js.map} +0 -0
- /package/dist/{chunk-PCRD6RK2.mjs.map → chunk-6Z7FIKB6.mjs.map} +0 -0
- /package/dist/{chunk-WQQC2IS2.js.map → chunk-HFIQYR5E.js.map} +0 -0
- /package/dist/{chunk-HS4KMVAP.mjs.map → chunk-NZWWNOXH.mjs.map} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkSS2LQM3Bjs = require('./chunk-SS2LQM3B.js');var
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkSS2LQM3Bjs = require('./chunk-SS2LQM3B.js');var _chunkQB7BC56Wjs = require('./chunk-QB7BC56W.js');var _dumbo = require('@event-driven-io/dumbo');var u=async(m,n,t)=>{let d=t&&"from"in t?`AND stream_position >= ${t.from}`:"",i=Number(t&&"to"in t?t.to:t&&"maxCount"in t&&t.maxCount?t.from+t.maxCount:NaN),p=isNaN(i)?"":`AND stream_position <= ${i}`,a=await _dumbo.mapRows.call(void 0, m.query(_dumbo.sql.call(void 0, `SELECT stream_id, stream_position, global_position, event_data, event_metadata, event_schema_version, event_type, event_id
|
|
2
2
|
FROM ${_chunkSS2LQM3Bjs.f.name}
|
|
3
|
-
WHERE stream_id = %L AND partition = %L AND is_archived = FALSE ${d} ${p}`,n,_nullishCoalesce(_optionalChain([t, 'optionalAccess', _ => _.partition]), () => (_chunkSS2LQM3Bjs.c)))),e=>{let r=
|
|
4
|
-
//# sourceMappingURL=chunk-
|
|
3
|
+
WHERE stream_id = %L AND partition = %L AND is_archived = FALSE ${d} ${p}`,n,_nullishCoalesce(_optionalChain([t, 'optionalAccess', _ => _.partition]), () => (_chunkSS2LQM3Bjs.c)))),e=>{let r=_chunkQB7BC56Wjs.j.call(void 0, e.event_type,e.event_data,e.event_metadata);return{...r,metadata:{...r.metadata,eventId:e.event_id,streamName:n,streamPosition:BigInt(e.stream_position),globalPosition:BigInt(e.global_position)}}});return a.length>0?{currentStreamVersion:a[a.length-1].metadata.streamPosition,events:a}:null};exports.a = u;
|
|
4
|
+
//# sourceMappingURL=chunk-5NYGSL2B.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as o,f as v}from"./chunk-ABNBEUC6.mjs";import{j as s}from"./chunk-
|
|
1
|
+
import{c as o,f as v}from"./chunk-ABNBEUC6.mjs";import{j as s}from"./chunk-PT4NEEE4.mjs";import{mapRows as E,sql as y}from"@event-driven-io/dumbo";var u=async(m,n,t)=>{let d=t&&"from"in t?`AND stream_position >= ${t.from}`:"",i=Number(t&&"to"in t?t.to:t&&"maxCount"in t&&t.maxCount?t.from+t.maxCount:NaN),p=isNaN(i)?"":`AND stream_position <= ${i}`,a=await E(m.query(y(`SELECT stream_id, stream_position, global_position, event_data, event_metadata, event_schema_version, event_type, event_id
|
|
2
2
|
FROM ${v.name}
|
|
3
3
|
WHERE stream_id = %L AND partition = %L AND is_archived = FALSE ${d} ${p}`,n,t?.partition??o)),e=>{let r=s(e.event_type,e.event_data,e.event_metadata);return{...r,metadata:{...r.metadata,eventId:e.event_id,streamName:n,streamPosition:BigInt(e.stream_position),globalPosition:BigInt(e.global_position)}}});return a.length>0?{currentStreamVersion:a[a.length-1].metadata.streamPosition,events:a}:null};export{u as a};
|
|
4
|
-
//# sourceMappingURL=chunk-
|
|
4
|
+
//# sourceMappingURL=chunk-6Z7FIKB6.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkEEYVFO3Gjs = require('./chunk-EEYVFO3G.js');var
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkEEYVFO3Gjs = require('./chunk-EEYVFO3G.js');var _chunkR5KGCWKQjs = require('./chunk-R5KGCWKQ.js');require('@event-driven-io/dumbo');var Q=[_chunkEEYVFO3Gjs.a,_chunkEEYVFO3Gjs.b,_chunkEEYVFO3Gjs.c,_chunkEEYVFO3Gjs.d,_chunkEEYVFO3Gjs.e,_chunkEEYVFO3Gjs.f,_chunkEEYVFO3Gjs.g,_chunkEEYVFO3Gjs.h,_chunkEEYVFO3Gjs.i,_chunkEEYVFO3Gjs.j,_chunkR5KGCWKQjs.a,_chunkEEYVFO3Gjs.k],P= exports.b =S=>S.withTransaction(({execute:L})=>L.batchCommand(Q));exports.a = Q; exports.b = P;
|
|
2
|
+
//# sourceMappingURL=chunk-HFIQYR5E.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{b as m,c as u,d as h,e as P,f as D,g,h as l,i as x,k as M}from"./chunk-PT4NEEE4.mjs";import"@event-driven-io/dumbo";import{pongoClient as G}from"@event-driven-io/pongo";import"@event-driven-io/dumbo";import{pongoClient as R}from"@event-driven-io/pongo";var w=({handle:e,canHandle:t})=>T({canHandle:t,handle:async(n,o)=>{let{connectionString:a,client:i}=o,p=R(a,{client:i});await e(n,{...o,pongo:p})}}),b=e=>{let{collectionName:t,getDocumentId:n,canHandle:o}=e;return w({handle:async(a,{pongo:i})=>{let p=i.db().collection(t);for(let v of a)await p.handle(n(v),async s=>"initialState"in e?await e.evolve(s??e.initialState(),v):await e.evolve(s,v))},canHandle:o})},k=e=>b({...e,getDocumentId:t=>t.metadata.streamName});import{dumbo as S}from"@event-driven-io/dumbo";import{v4 as f}from"uuid";var ee={for:e=>{{let{projection:t,...n}=e,{connectionString:o}=n;return a=>({when:(i,p)=>{let v=[],s=async c=>{let E=0n,r=p?.numberOfTimes??1;for(let d of[...a,...Array.from({length:r}).flatMap(()=>i)])v.push({...d,metadata:{globalPosition:++E,streamPosition:E,streamName:`test-${f()}`,eventId:f(),...d.metadata??{}}});await c.withTransaction(d=>j({events:v,projections:[t],connection:{connectionString:o,transaction:d}}))};return{then:async(c,E)=>{let r=S(n);try{await s(r);let d=await c({pool:r,connectionString:o});d!==void 0&&d===!1&&u(E??"Projection specification didn't match the criteria")}finally{await r.close()}},thenThrows:async(...c)=>{let E=S(n);try{throw await s(E),new m("Handler did not fail as expected")}catch(r){if(r instanceof m)throw r;if(c.length===0)return;if(!x(c[0])){P(c[0](r),`Error didn't match the error condition: ${r?.toString()}`);return}P(r instanceof c[0],`Caught error is not an instance of the expected type: ${r?.toString()}`),c[1]&&P(c[1](r),`Error didn't match the error condition: ${r?.toString()}`)}finally{await E.close()}}}}})}}},W=(e,t)=>({...t,metadata:{...t.metadata??{},streamName:t.metadata?.streamName??e}}),C=(e,t)=>t.map(n=>W(e,n)),te=C,I=(e,t)=>async({pool:{execute:n}})=>{let o=await n.query(e);l(t).containsExactlyInAnyOrder(...o.rows)},ne={query:e=>({resultRows:{toBeTheSame:t=>I(e,t)}})};var re={projections:[]},j=async e=>{let{projections:t,events:n,connection:{transaction:o,connectionString:a}}=e,i=n.map(s=>s.type),p=t.filter(s=>s.canHandle.some(c=>i.includes(c))),v=await o.connection.open();for(let s of p)await s.handle(n,{connectionString:a,client:v,transaction:o,execute:o.execute})},T=e=>M(e),H=(e,...t)=>T({canHandle:t,handle:async(n,o)=>{let a=await e(n,o);await o.execute.batchCommand(a)}}),se=(e,...t)=>H(async(n,o)=>{let a=[];for(let i of n)a.push(await e(i,o));return a},...t);var y=(e,t)=>{let{pool:n,connectionString:o,inDatabase:a,inCollection:i}=t;return n.withConnection(async p=>{let v=G(o,{connection:p});try{let s=v.db(a).collection(i);return e(s)}finally{await v.close()}})},Q=e=>{let{_id:t,...n}=e;return n},A=(e,t)=>("_id"in t&&D(t._id,e._id,`Document ids are not matching! Expected: ${t._id}, actual: ${e._id}`),h(Q(e),Q(t))),N=(e,t)=>n=>y(async o=>{let a=await o.findOne("withId"in t?{_id:t.withId}:t.matchingFilter);g(a),A(a,e)},{...t,...n}),F=(e,t)=>n=>y(async o=>{let a=await o.find("withId"in t?{_id:t.withId}:t.matchingFilter);D(e.length,a.length,"Different Documents Count than expected");for(let i=0;i<e.length;i++)l(a).contains(e[i])},{...t,...n}),_=(e,t)=>n=>y(async o=>{let a=await o.find("withId"in t?{_id:t.withId}:t.matchingFilter);D(e,a.length,"Different Documents Count than expected")},{...t,...n}),O=e=>t=>y(async n=>{let o=await n.find("withId"in e?{_id:e.withId}:e.matchingFilter);l(o).isNotEmpty()},{...e,...t}),L=e=>t=>y(async n=>{let o=await n.findOne("withId"in e?{_id:e.withId}:e.matchingFilter);g(o)},{...e,...t}),Pe={fromCollection:e=>({withId:t=>({toBeEqual:n=>N(n,{withId:t,inCollection:e}),toExist:()=>O({withId:t,inCollection:e}),notToExist:()=>L({withId:t,inCollection:e})}),matching:t=>({toBeTheSame:n=>F(n,{matchingFilter:t,inCollection:e}),toHaveCount:n=>_(n,{matchingFilter:t,inCollection:e}),toExist:()=>O({matchingFilter:t,inCollection:e}),notToExist:()=>L({matchingFilter:t,inCollection:e})})})};export{N as a,F as b,_ as c,O as d,L as e,Pe as f,w as g,b as h,k as i,ee as j,W as k,C as l,te as m,I as n,ne as o,re as p,j as q,T as r,H as s,se as t};
|
|
2
|
+
//# sourceMappingURL=chunk-JPTXK5ZT.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/eventStore/projections/pongo/pongoProjectionSpec.ts","../src/eventStore/projections/index.ts","../src/eventStore/projections/pongo/projections.ts","../src/eventStore/projections/postgresProjectionSpec.ts"],"sourcesContent":["import { type Dumbo } from '@event-driven-io/dumbo';\nimport {\n assertDeepEqual,\n assertEqual,\n assertIsNotNull,\n assertThatArray,\n} from '@event-driven-io/emmett';\nimport {\n pongoClient,\n type PongoCollection,\n type PongoDocument,\n type PongoFilter,\n type WithId,\n} from '@event-driven-io/pongo';\nimport { type PostgreSQLProjectionAssert } from '..';\n\nexport type PongoAssertOptions = {\n inCollection: string;\n inDatabase?: string;\n};\n\nconst withCollection = (\n handle: (collection: PongoCollection<PongoDocument>) => Promise<void>,\n options: {\n pool: Dumbo;\n connectionString: string;\n } & PongoAssertOptions,\n) => {\n const { pool, connectionString, inDatabase, inCollection } = options;\n\n return pool.withConnection(async (connection) => {\n const pongo = pongoClient(connectionString, {\n connection,\n });\n try {\n const collection = pongo.db(inDatabase).collection(inCollection);\n\n return handle(collection);\n } finally {\n await pongo.close();\n }\n });\n};\n\nconst withoutId = <Doc extends PongoDocument | WithId<PongoDocument>>(\n doc: Doc,\n) => {\n const { _id, ...without } = doc;\n\n return without;\n};\n\nconst assertDocumentsEqual = <\n Doc extends PongoDocument | WithId<PongoDocument>,\n>(\n actual: PongoDocument,\n expected: Doc,\n) => {\n if ('_id' in expected)\n assertEqual(\n expected._id,\n actual._id,\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `Document ids are not matching! Expected: ${expected._id}, actual: ${actual._id}`,\n );\n\n return assertDeepEqual(withoutId(actual), withoutId(expected));\n};\n\ntype FilterOrId<Doc extends PongoDocument | WithId<PongoDocument>> =\n | { withId: string }\n | {\n matchingFilter: PongoFilter<Doc>;\n };\n\nexport const documentExists =\n <Doc extends PongoDocument | WithId<PongoDocument>>(\n document: Doc,\n options: PongoAssertOptions & FilterOrId<Doc>,\n ): PostgreSQLProjectionAssert =>\n (assertOptions) =>\n withCollection(\n async (collection) => {\n const result = await collection.findOne(\n 'withId' in options\n ? { _id: options.withId }\n : options.matchingFilter,\n );\n\n assertIsNotNull(result);\n\n assertDocumentsEqual(result, document);\n },\n { ...options, ...assertOptions },\n );\n\nexport const documentsAreTheSame =\n <Doc extends PongoDocument | WithId<PongoDocument>>(\n documents: Doc[],\n options: PongoAssertOptions & FilterOrId<Doc>,\n ): PostgreSQLProjectionAssert =>\n (assertOptions) =>\n withCollection(\n async (collection) => {\n const result = await collection.find(\n 'withId' in options\n ? { _id: options.withId }\n : options.matchingFilter,\n );\n\n assertEqual(\n documents.length,\n result.length,\n 'Different Documents Count than expected',\n );\n\n for (let i = 0; i < documents.length; i++) {\n assertThatArray(result).contains(documents[i]!);\n }\n },\n { ...options, ...assertOptions },\n );\n\nexport const documentsMatchingHaveCount =\n <Doc extends PongoDocument | WithId<PongoDocument>>(\n expectedCount: number,\n options: PongoAssertOptions & FilterOrId<Doc>,\n ): PostgreSQLProjectionAssert =>\n (assertOptions) =>\n withCollection(\n async (collection) => {\n const result = await collection.find(\n 'withId' in options\n ? { _id: options.withId }\n : options.matchingFilter,\n );\n\n assertEqual(\n expectedCount,\n result.length,\n 'Different Documents Count than expected',\n );\n },\n { ...options, ...assertOptions },\n );\n\nexport const documentMatchingExists =\n <Doc extends PongoDocument | WithId<PongoDocument>>(\n options: PongoAssertOptions & FilterOrId<Doc>,\n ): PostgreSQLProjectionAssert =>\n (assertOptions) =>\n withCollection(\n async (collection) => {\n const result = await collection.find(\n 'withId' in options\n ? { _id: options.withId }\n : options.matchingFilter,\n );\n\n assertThatArray(result).isNotEmpty();\n },\n { ...options, ...assertOptions },\n );\n\nexport const documentDoesNotExist =\n <Doc extends PongoDocument | WithId<PongoDocument>>(\n options: PongoAssertOptions & FilterOrId<Doc>,\n ): PostgreSQLProjectionAssert =>\n (assertOptions) =>\n withCollection(\n async (collection) => {\n const result = await collection.findOne(\n 'withId' in options\n ? { _id: options.withId }\n : options.matchingFilter,\n );\n\n assertIsNotNull(result);\n },\n { ...options, ...assertOptions },\n );\n\nexport const expectPongoDocuments = {\n fromCollection: <Doc extends PongoDocument | WithId<PongoDocument>>(\n collectionName: string,\n ) => {\n return {\n withId: (id: string) => {\n return {\n toBeEqual: (document: Doc) =>\n documentExists(document, {\n withId: id,\n inCollection: collectionName,\n }),\n toExist: () =>\n documentMatchingExists({\n withId: id,\n inCollection: collectionName,\n }),\n notToExist: () =>\n documentDoesNotExist({\n withId: id,\n inCollection: collectionName,\n }),\n };\n },\n matching: <Doc extends PongoDocument | WithId<PongoDocument>>(\n filter: PongoFilter<Doc>,\n ) => {\n return {\n toBeTheSame: (documents: Doc[]) =>\n documentsAreTheSame<Doc>(documents, {\n matchingFilter: filter,\n inCollection: collectionName,\n }),\n toHaveCount: (expectedCount: number) =>\n documentsMatchingHaveCount(expectedCount, {\n matchingFilter: filter,\n inCollection: collectionName,\n }),\n toExist: () =>\n documentMatchingExists({\n matchingFilter: filter,\n inCollection: collectionName,\n }),\n notToExist: () =>\n documentDoesNotExist({\n matchingFilter: filter,\n inCollection: collectionName,\n }),\n };\n },\n };\n },\n};\n","import {\n type NodePostgresClient,\n type NodePostgresTransaction,\n type SQL,\n type SQLExecutor,\n} from '@event-driven-io/dumbo';\nimport {\n projection,\n type CanHandle,\n type Event,\n type EventMetaDataOf,\n type ProjectionHandler,\n type ReadEvent,\n type ReadEventMetadata,\n type TypedProjectionDefinition,\n} from '@event-driven-io/emmett';\nimport type { PostgresEventStoreOptions } from '../postgreSQLEventStore';\n\nexport type PostgreSQLProjectionHandlerContext = {\n connectionString: string;\n client: NodePostgresClient;\n execute: SQLExecutor;\n transaction: NodePostgresTransaction;\n};\n\nexport type PostgreSQLProjectionHandler<\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadata = EventMetaDataOf<EventType> & ReadEventMetadata,\n> = ProjectionHandler<\n EventType,\n EventMetaDataType,\n PostgreSQLProjectionHandlerContext\n>;\n\nexport interface PostgreSQLProjectionDefinition<\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadata = EventMetaDataOf<EventType> & ReadEventMetadata,\n> extends TypedProjectionDefinition<\n EventType,\n EventMetaDataType,\n PostgreSQLProjectionHandlerContext\n > {}\n\nexport const defaultPostgreSQLProjectionOptions: PostgresEventStoreOptions = {\n projections: [],\n};\n\nexport type ProjectionHandlerOptions<\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadata = EventMetaDataOf<EventType> & ReadEventMetadata,\n> = {\n events: ReadEvent<EventType, EventMetaDataType>[];\n projections: PostgreSQLProjectionDefinition<EventType>[];\n connection: {\n connectionString: string;\n transaction: NodePostgresTransaction;\n };\n};\n\nexport const handleProjections = async <\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadata = EventMetaDataOf<EventType> & ReadEventMetadata,\n>(\n options: ProjectionHandlerOptions<EventType, EventMetaDataType>,\n): Promise<void> => {\n const {\n projections: allProjections,\n events,\n connection: { transaction, connectionString },\n } = options;\n\n const eventTypes = events.map((e) => e.type);\n\n const projections = allProjections.filter((p) =>\n p.canHandle.some((type) => eventTypes.includes(type)),\n );\n\n const client = (await transaction.connection.open()) as NodePostgresClient;\n\n for (const projection of projections) {\n await projection.handle(events, {\n connectionString,\n client,\n transaction,\n execute: transaction.execute,\n });\n }\n};\n\nexport const postgreSQLProjection = <\n EventType extends Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadata = EventMetaDataOf<EventType> & ReadEventMetadata,\n>(\n definition: PostgreSQLProjectionDefinition<EventType>,\n): PostgreSQLProjectionDefinition =>\n projection<\n EventType,\n EventMetaDataType,\n PostgreSQLProjectionHandlerContext,\n PostgreSQLProjectionDefinition<EventType>\n >(definition) as PostgreSQLProjectionDefinition;\n\nexport const postgreSQLRawBatchSQLProjection = <EventType extends Event>(\n handle: (\n events: EventType[],\n context: PostgreSQLProjectionHandlerContext,\n ) => Promise<SQL[]> | SQL[],\n ...canHandle: CanHandle<EventType>\n): PostgreSQLProjectionDefinition =>\n postgreSQLProjection<EventType>({\n canHandle,\n handle: async (events, context) => {\n const sqls: SQL[] = await handle(events, context);\n\n await context.execute.batchCommand(sqls);\n },\n });\n\nexport const postgreSQLRawSQLProjection = <EventType extends Event>(\n handle: (\n event: EventType,\n context: PostgreSQLProjectionHandlerContext,\n ) => Promise<SQL> | SQL,\n ...canHandle: CanHandle<EventType>\n): PostgreSQLProjectionDefinition =>\n postgreSQLRawBatchSQLProjection<EventType>(\n async (events, context) => {\n const sqls: SQL[] = [];\n\n for (const event of events) {\n sqls.push(await handle(event, context));\n }\n return sqls;\n },\n ...canHandle,\n );\n\nexport * from './pongo';\nexport * from './postgresProjectionSpec';\n","import {\n type CanHandle,\n type Event,\n type EventMetaDataOf,\n type ReadEvent,\n type ReadEventMetadataWithGlobalPosition,\n} from '@event-driven-io/emmett';\nimport {\n pongoClient,\n type PongoClient,\n type PongoDocument,\n} from '@event-driven-io/pongo';\nimport {\n postgreSQLProjection,\n type PostgreSQLProjectionDefinition,\n type PostgreSQLProjectionHandlerContext,\n} from '..';\n\nexport type PongoProjectionHandlerContext =\n PostgreSQLProjectionHandlerContext & {\n pongo: PongoClient;\n };\n\nexport type PongoWithNotNullDocumentEvolve<\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition = EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition,\n> =\n | ((\n document: Document,\n event: ReadEvent<EventType, EventMetaDataType>,\n ) => Document | null)\n | ((\n document: Document,\n event: ReadEvent<EventType>,\n ) => Promise<Document | null>);\n\nexport type PongoWithNullableDocumentEvolve<\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition = EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition,\n> =\n | ((\n document: Document | null,\n event: ReadEvent<EventType, EventMetaDataType>,\n ) => Document | null)\n | ((\n document: Document | null,\n event: ReadEvent<EventType>,\n ) => Promise<Document | null>);\n\nexport type PongoDocumentEvolve<\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition = EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition,\n> =\n | PongoWithNotNullDocumentEvolve<Document, EventType, EventMetaDataType>\n | PongoWithNullableDocumentEvolve<Document, EventType, EventMetaDataType>;\n\nexport type PongoProjectionOptions<\n EventType extends Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition = EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition,\n> = {\n handle: (\n events: ReadEvent<EventType, EventMetaDataType>[],\n context: PongoProjectionHandlerContext,\n ) => Promise<void>;\n canHandle: CanHandle<EventType>;\n};\n\nexport const pongoProjection = <\n EventType extends Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition = EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition,\n>({\n handle,\n canHandle,\n}: PongoProjectionOptions<\n EventType,\n EventMetaDataType\n>): PostgreSQLProjectionDefinition =>\n postgreSQLProjection<EventType, EventMetaDataType>({\n canHandle,\n handle: async (events, context) => {\n const { connectionString, client } = context;\n const pongo = pongoClient(connectionString, { client });\n await handle(events as ReadEvent<EventType, EventMetaDataType>[], {\n ...context,\n pongo,\n });\n },\n });\n\nexport type PongoMultiStreamProjectionOptions<\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition = EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition,\n> = {\n canHandle: CanHandle<EventType>;\n\n collectionName: string;\n getDocumentId: (event: ReadEvent<EventType>) => string;\n} & (\n | {\n evolve: PongoWithNullableDocumentEvolve<\n Document,\n EventType,\n EventMetaDataType\n >;\n }\n | {\n evolve: PongoWithNotNullDocumentEvolve<\n Document,\n EventType,\n EventMetaDataType\n >;\n initialState: () => Document;\n }\n);\n\nexport const pongoMultiStreamProjection = <\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition = EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition,\n>(\n options: PongoMultiStreamProjectionOptions<\n Document,\n EventType,\n EventMetaDataType\n >,\n): PostgreSQLProjectionDefinition => {\n const { collectionName, getDocumentId, canHandle } = options;\n\n return pongoProjection({\n handle: async (events, { pongo }) => {\n const collection = pongo.db().collection<Document>(collectionName);\n\n for (const event of events) {\n await collection.handle(getDocumentId(event), async (document) => {\n return 'initialState' in options\n ? await options.evolve(\n document ?? options.initialState(),\n event as ReadEvent<EventType, EventMetaDataType>,\n )\n : await options.evolve(\n document,\n event as ReadEvent<EventType, EventMetaDataType>,\n );\n });\n }\n },\n canHandle,\n });\n};\n\nexport type PongoSingleStreamProjectionOptions<\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition = EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition,\n> = {\n canHandle: CanHandle<EventType>;\n\n collectionName: string;\n} & (\n | {\n evolve: PongoWithNullableDocumentEvolve<\n Document,\n EventType,\n EventMetaDataType\n >;\n }\n | {\n evolve: PongoWithNotNullDocumentEvolve<\n Document,\n EventType,\n EventMetaDataType\n >;\n initialState: () => Document;\n }\n);\n\nexport const pongoSingleStreamProjection = <\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition = EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition,\n>(\n options: PongoSingleStreamProjectionOptions<\n Document,\n EventType,\n EventMetaDataType\n >,\n): PostgreSQLProjectionDefinition => {\n return pongoMultiStreamProjection<Document, EventType, EventMetaDataType>({\n ...options,\n getDocumentId: (event) => event.metadata.streamName,\n });\n};\n","import {\n dumbo,\n type Dumbo,\n type DumboOptions,\n type QueryResultRow,\n type SQL,\n} from '@event-driven-io/dumbo';\nimport {\n assertFails,\n AssertionError,\n assertThatArray,\n assertTrue,\n isErrorConstructor,\n type Event,\n type EventMetaDataOf,\n type ReadEvent,\n type ReadEventMetadataWithGlobalPosition,\n type ThenThrows,\n} from '@event-driven-io/emmett';\nimport { v4 as uuid } from 'uuid';\nimport { handleProjections, type PostgreSQLProjectionDefinition } from '.';\n\nexport type PostgreSQLProjectionSpecEvent<\n EventType extends Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition = EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition,\n> = EventType & {\n metadata?: Partial<EventMetaDataType>;\n};\n\nexport type PostgreSQLProjectionSpecWhenOptions = { numberOfTimes: number };\n\nexport type PostgreSQLProjectionSpec<EventType extends Event> = (\n givenEvents: PostgreSQLProjectionSpecEvent<EventType>[],\n) => {\n when: (\n events: PostgreSQLProjectionSpecEvent<EventType>[],\n options?: PostgreSQLProjectionSpecWhenOptions,\n ) => {\n then: (\n assert: PostgreSQLProjectionAssert,\n message?: string,\n ) => Promise<void>;\n thenThrows: <ErrorType extends Error = Error>(\n ...args: Parameters<ThenThrows<ErrorType>>\n ) => Promise<void>;\n };\n};\n\nexport type PostgreSQLProjectionAssert = (options: {\n pool: Dumbo;\n connectionString: string;\n}) => Promise<void | boolean>;\n\nexport type PostgreSQLProjectionSpecOptions = {\n projection: PostgreSQLProjectionDefinition;\n} & DumboOptions;\n\nexport const PostgreSQLProjectionSpec = {\n for: <EventType extends Event>(\n options: PostgreSQLProjectionSpecOptions,\n ): PostgreSQLProjectionSpec<EventType> => {\n {\n const { projection, ...dumoOptions } = options;\n const { connectionString } = dumoOptions;\n\n return (givenEvents: PostgreSQLProjectionSpecEvent<EventType>[]) => {\n return {\n when: (\n events: PostgreSQLProjectionSpecEvent<EventType>[],\n options?: PostgreSQLProjectionSpecWhenOptions,\n ) => {\n const allEvents: ReadEvent<\n EventType,\n ReadEventMetadataWithGlobalPosition\n >[] = [];\n\n const run = async (pool: Dumbo) => {\n let globalPosition = 0n;\n const numberOfTimes = options?.numberOfTimes ?? 1;\n\n for (const event of [\n ...givenEvents,\n ...Array.from({ length: numberOfTimes }).flatMap(() => events),\n ]) {\n allEvents.push({\n ...event,\n metadata: {\n ...{\n globalPosition: ++globalPosition,\n streamPosition: globalPosition,\n streamName: `test-${uuid()}`,\n eventId: uuid(),\n },\n ...(event.metadata ?? {}),\n },\n });\n }\n\n await pool.withTransaction((transaction) =>\n handleProjections({\n events: allEvents,\n projections: [projection],\n connection: {\n connectionString,\n transaction,\n },\n }),\n );\n };\n\n return {\n then: async (\n assert: PostgreSQLProjectionAssert,\n message?: string,\n ): Promise<void> => {\n const pool = dumbo(dumoOptions);\n try {\n await run(pool);\n\n const succeeded = await assert({ pool, connectionString });\n\n if (succeeded !== undefined && succeeded === false)\n assertFails(\n message ??\n \"Projection specification didn't match the criteria\",\n );\n } finally {\n await pool.close();\n }\n },\n thenThrows: async <ErrorType extends Error>(\n ...args: Parameters<ThenThrows<ErrorType>>\n ): Promise<void> => {\n const pool = dumbo(dumoOptions);\n try {\n await run(pool);\n throw new AssertionError('Handler did not fail as expected');\n } catch (error) {\n if (error instanceof AssertionError) throw error;\n\n if (args.length === 0) return;\n\n if (!isErrorConstructor(args[0])) {\n assertTrue(\n args[0](error as ErrorType),\n `Error didn't match the error condition: ${error?.toString()}`,\n );\n return;\n }\n\n assertTrue(\n error instanceof args[0],\n `Caught error is not an instance of the expected type: ${error?.toString()}`,\n );\n\n if (args[1]) {\n assertTrue(\n args[1](error as ErrorType),\n `Error didn't match the error condition: ${error?.toString()}`,\n );\n }\n } finally {\n await pool.close();\n }\n },\n };\n },\n };\n };\n }\n },\n};\n\nexport const eventInStream = <\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition = EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition,\n>(\n streamName: string,\n event: PostgreSQLProjectionSpecEvent<EventType, EventMetaDataType>,\n): PostgreSQLProjectionSpecEvent<EventType, EventMetaDataType> => {\n return {\n ...event,\n metadata: {\n ...(event.metadata ?? {}),\n streamName: event.metadata?.streamName ?? streamName,\n } as Partial<EventMetaDataType>,\n };\n};\n\nexport const eventsInStream = <\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition = EventMetaDataOf<EventType> &\n ReadEventMetadataWithGlobalPosition,\n>(\n streamName: string,\n events: PostgreSQLProjectionSpecEvent<EventType, EventMetaDataType>[],\n): PostgreSQLProjectionSpecEvent<EventType, EventMetaDataType>[] => {\n return events.map((e) => eventInStream(streamName, e));\n};\n\nexport const newEventsInStream = eventsInStream;\n\nexport const assertSQLQueryResultMatches =\n <T extends QueryResultRow>(sql: SQL, rows: T[]): PostgreSQLProjectionAssert =>\n async ({ pool: { execute } }) => {\n const result = await execute.query<T>(sql);\n\n assertThatArray(rows).containsExactlyInAnyOrder(...result.rows);\n };\n\nexport const expectSQL = {\n query: (sql: SQL) => ({\n resultRows: {\n toBeTheSame: <T extends QueryResultRow>(rows: T[]) =>\n assertSQLQueryResultMatches(sql, rows),\n },\n }),\n};\n"],"mappings":"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","names":["pongoClient","pongoClient","pongoProjection","handle","canHandle","postgreSQLProjection","events","context","connectionString","client","pongo","pongoClient","pongoMultiStreamProjection","options","collectionName","getDocumentId","collection","event","document","pongoSingleStreamProjection","dumbo","uuid","PostgreSQLProjectionSpec","options","projection","dumoOptions","connectionString","givenEvents","events","allEvents","run","pool","globalPosition","numberOfTimes","event","uuid","transaction","handleProjections","assert","message","dumbo","succeeded","p","args","l","error","w","s","eventInStream","streamName","eventsInStream","e","newEventsInStream","assertSQLQueryResultMatches","sql","rows","execute","result","q","expectSQL","defaultPostgreSQLProjectionOptions","handleProjections","options","allProjections","events","transaction","connectionString","eventTypes","e","projections","p","type","client","projection","postgreSQLProjection","definition","a","postgreSQLRawBatchSQLProjection","handle","canHandle","context","sqls","postgreSQLRawSQLProjection","event","withCollection","handle","options","pool","connectionString","inDatabase","inCollection","connection","pongo","pongoClient","collection","withoutId","doc","_id","without","assertDocumentsEqual","actual","expected","c","x","documentExists","document","assertOptions","result","y","documentsAreTheSame","documents","q","documentsMatchingHaveCount","expectedCount","documentMatchingExists","documentDoesNotExist","expectPongoDocuments","collectionName","id","filter"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as e,b as t,c as a,d as r,e as d,f as n,g as s,h as m,i,j as l,k as p}from"./chunk-UWD6GOZC.mjs";import{a as o}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import{a as e,b as t,c as a,d as r,e as d,f as n,g as s,h as m,i,j as l,k as p}from"./chunk-UWD6GOZC.mjs";import{a as o}from"./chunk-SIRCKLWA.mjs";import"@event-driven-io/dumbo";var Q=[e,t,a,r,d,n,s,m,i,l,o,p],P=S=>S.withTransaction(({execute:L})=>L.batchCommand(Q));export{Q as a,P as b};
|
|
2
|
+
//# sourceMappingURL=chunk-NZWWNOXH.mjs.map
|
|
@@ -4,4 +4,4 @@ is not equal to
|
|
|
4
4
|
${l.stringify(e)}`)};function o(e,t){if(!e)throw new i(t??"Condition is false")}function h(e,t){if(!e)throw new i(t??"Condition is not truthy")}function c(e,t,r){if(e!==t)throw new i(r??`Objects are not equal:
|
|
5
5
|
Expected: ${l.stringify(e)}
|
|
6
6
|
Actual:${l.stringify(t)}`)}function m(e,t,r){if(e===t)throw new i(r??`Objects are equal: ${l.stringify(e)}`)}function A(e){m(e,null),h(e)}var k=e=>({isEmpty:()=>c(e.length,0),isNotEmpty:()=>m(e.length,0),hasSize:t=>c(e.length,t),containsElements:(...t)=>{o(t.every(r=>t.some(a=>s(r,a))))},containsExactlyInAnyOrder:(...t)=>{c(e.length,t.length),o(e.every(r=>t.some(a=>s(r,a))))},containsExactlyInAnyOrderElementsOf:t=>{c(e.length,t.length),o(e.every(r=>t.some(a=>s(r,a))))},containsExactlyElementsOf:t=>{c(e.length,t.length);for(let r=0;r<e.length;r++)o(s(e[r],t[r]))},containsExactly:t=>{c(e.length,1),o(s(e[0],t))},contains:t=>{o(e.some(r=>s(r,t)))},containsOnlyOnceElementsOf:t=>{o(t.map(r=>e.filter(a=>s(a,r)).length).filter(r=>r===1).length===t.length)},containsAnyOf:(...t)=>{o(e.some(r=>t.some(a=>s(r,a))))},allMatch:t=>{o(e.every(t))},anyMatches:t=>{o(e.some(t))},allMatchAsync:async t=>{for(let r of e)o(await t(r))}});var g=(e=>(e.NOT_A_NONEMPTY_STRING="NOT_A_NONEMPTY_STRING",e.NOT_A_POSITIVE_NUMBER="NOT_A_POSITIVE_NUMBER",e.NOT_AN_UNSIGNED_BIGINT="NOT_AN_UNSIGNED_BIGINT",e))(g||{}),y=e=>typeof e=="number"&&e===e,w=e=>typeof e=="string";var E=e=>typeof e=="function"&&e.prototype&&e.prototype.constructor===e,d=class S extends Error{errorCode;constructor(t){let r=t&&typeof t=="object"&&"errorCode"in t?t.errorCode:y(t)?t:500,a=t&&typeof t=="object"&&"message"in t?t.message:w(t)?t:`Error with status code '${r}' ocurred during Emmett processing`;super(a),this.errorCode=r,Object.setPrototypeOf(this,S.prototype)}},f=class b extends d{constructor(t,r,a){super({errorCode:412,message:a??`Expected version ${r.toString()} does not match current ${t?.toString()}`}),this.current=t,this.expected=r,Object.setPrototypeOf(this,b.prototype)}};var I=(e,t,r)=>({type:e,data:t,metadata:r});var M=e=>e;var j="STREAM_EXISTS",v="STREAM_DOES_NOT_EXIST",x="NO_CONCURRENCY_CHECK";var _=class N extends f{constructor(t,r){super(t?.toString(),r?.toString()),Object.setPrototypeOf(this,N.prototype)}};import ge from"async-retry";import{TransformStream as we}from"web-streams-polyfill";import{v4 as $e}from"uuid";export{l as a,i as b,T as c,C as d,o as e,c as f,A as g,k as h,E as i,I as j,M as k,j as l,v as m,x as n,_ as o};
|
|
7
|
-
//# sourceMappingURL=chunk-
|
|
7
|
+
//# sourceMappingURL=chunk-PT4NEEE4.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../emmett/src/serialization/json/JSONParser.ts","../../emmett/src/utils/deepEquals.ts","../../emmett/src/testing/assertions.ts","../../emmett/src/validation/index.ts","../../emmett/src/errors/index.ts","../../emmett/src/validation/dates.ts","../../emmett/src/typing/event.ts","../../emmett/src/projections/index.ts","../../emmett/src/eventStore/expectedVersion.ts","../../emmett/src/streaming/restream.ts","../../emmett/src/eventStore/inMemoryEventStore.ts"],"sourcesContent":["export class ParseError extends Error {\n constructor(text: string) {\n super(`Cannot parse! ${text}`);\n }\n}\n\nexport type Mapper<From, To = From> =\n | ((value: unknown) => To)\n | ((value: Partial<From>) => To)\n | ((value: From) => To)\n | ((value: Partial<To>) => To)\n | ((value: To) => To)\n | ((value: Partial<To | From>) => To)\n | ((value: To | From) => To);\n\nexport type MapperArgs<From, To = From> = Partial<From> &\n From &\n Partial<To> &\n To;\n\nexport type ParseOptions<From, To = From> = {\n reviver?: (key: string, value: unknown) => unknown;\n map?: Mapper<From, To>;\n typeCheck?: <To>(value: unknown) => value is To;\n};\n\nexport type StringifyOptions<From, To = From> = {\n map?: Mapper<From, To>;\n};\n\nexport const JSONParser = {\n stringify: <From, To = From>(\n value: From,\n options?: StringifyOptions<From, To>,\n ) => {\n return JSON.stringify(\n options?.map ? options.map(value as MapperArgs<From, To>) : value,\n //TODO: Consider adding support to DateTime and adding specific format to mark that's a bigint\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n (_, v) => (typeof v === 'bigint' ? v.toString() : v),\n );\n },\n parse: <From, To = From>(\n text: string,\n options?: ParseOptions<From, To>,\n ): To | undefined => {\n const parsed: unknown = JSON.parse(text, options?.reviver);\n\n if (options?.typeCheck && !options?.typeCheck<To>(parsed))\n throw new ParseError(text);\n\n return options?.map\n ? options.map(parsed as MapperArgs<From, To>)\n : (parsed as To | undefined);\n },\n};\n","export const deepEquals = <T>(left: T, right: T): boolean => {\n if (isEquatable(left)) {\n return left.equals(right);\n }\n\n if (Array.isArray(left)) {\n return (\n Array.isArray(right) &&\n left.length === right.length &&\n left.every((val, index) => deepEquals(val, right[index]))\n );\n }\n\n if (\n typeof left !== 'object' ||\n typeof right !== 'object' ||\n left === null ||\n right === null\n ) {\n return left === right;\n }\n\n if (Array.isArray(right)) return false;\n\n const keys1 = Object.keys(left);\n const keys2 = Object.keys(right);\n\n if (\n keys1.length !== keys2.length ||\n !keys1.every((key) => keys2.includes(key))\n )\n return false;\n\n for (const key in left) {\n if (left[key] instanceof Function && right[key] instanceof Function)\n continue;\n\n const isEqual = deepEquals(left[key], right[key]);\n if (!isEqual) {\n return false;\n }\n }\n\n return true;\n};\n\nexport type Equatable<T> = { equals: (right: T) => boolean } & T;\n\nexport const isEquatable = <T>(left: T): left is Equatable<T> => {\n return (\n left &&\n typeof left === 'object' &&\n 'equals' in left &&\n typeof left['equals'] === 'function'\n );\n};\n","import { JSONParser } from '../serialization';\nimport type { DefaultRecord } from '../typing';\nimport { deepEquals } from '../utils';\n\nexport class AssertionError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\nexport const isSubset = (superObj: unknown, subObj: unknown): boolean => {\n const sup = superObj as DefaultRecord;\n const sub = subObj as DefaultRecord;\n\n assertOk(sup);\n assertOk(sub);\n\n return Object.keys(sub).every((ele: string) => {\n if (typeof sub[ele] == 'object') {\n return isSubset(sup[ele], sub[ele]);\n }\n return sub[ele] === sup[ele];\n });\n};\n\nexport const assertFails = (message?: string) => {\n throw new AssertionError(message ?? 'That should not ever happened, right?');\n};\n\nexport const assertThrowsAsync = async <TError extends Error>(\n fun: () => Promise<void>,\n errorCheck?: (error: Error) => boolean,\n): Promise<TError> => {\n try {\n await fun();\n throw new AssertionError(\"Function didn't throw expected error\");\n } catch (error) {\n const typedError = error as TError;\n if (errorCheck) assertTrue(errorCheck(typedError));\n return typedError;\n }\n};\n\nexport const assertThrows = <TError extends Error>(\n fun: () => void,\n errorCheck?: (error: Error) => boolean,\n): TError => {\n try {\n fun();\n throw new AssertionError(\"Function didn't throw expected error\");\n } catch (error) {\n const typedError = error as TError;\n if (errorCheck) assertTrue(errorCheck(typedError));\n return typedError;\n }\n};\nexport const assertMatches = (\n actual: unknown,\n expected: unknown,\n message?: string,\n) => {\n if (!isSubset(actual, expected))\n throw new AssertionError(\n message ??\n `subObj:\\n${JSONParser.stringify(expected)}\\nis not subset of\\n${JSONParser.stringify(actual)}`,\n );\n};\n\nexport const assertDeepEqual = <T = unknown>(\n actual: T,\n expected: T,\n message?: string,\n) => {\n if (!deepEquals(actual, expected))\n throw new AssertionError(\n message ??\n `subObj:\\n${JSONParser.stringify(expected)}\\nis not equal to\\n${JSONParser.stringify(actual)}`,\n );\n};\n\nexport const assertNotDeepEqual = <T = unknown>(\n actual: T,\n expected: T,\n message?: string,\n) => {\n if (deepEquals(actual, expected))\n throw new AssertionError(\n message ??\n `subObj:\\n${JSONParser.stringify(expected)}\\nis equals to\\n${JSONParser.stringify(actual)}`,\n );\n};\n\nexport const assertThat = <T>(item: T) => {\n return {\n isEqualTo: (other: T) => assertTrue(deepEquals(item, other)),\n };\n};\n\nexport function assertFalse(\n condition: boolean,\n message?: string,\n): asserts condition is false {\n if (condition) throw new AssertionError(message ?? `Condition is false`);\n}\n\nexport function assertTrue(\n condition: boolean,\n message?: string,\n): asserts condition is true {\n if (!condition) throw new AssertionError(message ?? `Condition is false`);\n}\n\nexport function assertOk<T>(\n obj: T | null | undefined,\n message?: string,\n): asserts obj is T {\n if (!obj) throw new AssertionError(message ?? `Condition is not truthy`);\n}\n\nexport function assertEqual<T>(\n expected: T | null | undefined,\n actual: T | null | undefined,\n message?: string,\n): void {\n if (expected !== actual)\n throw new AssertionError(\n message ??\n `Objects are not equal:\\nExpected: ${JSONParser.stringify(expected)}\\nActual:${JSONParser.stringify(actual)}`,\n );\n}\n\nexport function assertNotEqual<T>(\n obj: T | null | undefined,\n other: T | null | undefined,\n message?: string,\n): void {\n if (obj === other)\n throw new AssertionError(\n message ?? `Objects are equal: ${JSONParser.stringify(obj)}`,\n );\n}\n\nexport function assertIsNotNull<T extends object | bigint>(\n result: T | null,\n): asserts result is T {\n assertNotEqual(result, null);\n assertOk(result);\n}\n\nexport function assertIsNull<T extends object>(\n result: T | null,\n): asserts result is null {\n assertEqual(result, null);\n}\n\ntype Call = {\n arguments: unknown[];\n result: unknown;\n target: unknown;\n this: unknown;\n};\n\nexport type ArgumentMatcher = (arg: unknown) => boolean;\n\nexport const argValue =\n <T>(value: T): ArgumentMatcher =>\n (arg) =>\n deepEquals(arg, value);\n\nexport const argMatches =\n <T>(matches: (arg: T) => boolean): ArgumentMatcher =>\n (arg) =>\n matches(arg as T);\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport type MockedFunction = Function & { mock?: { calls: Call[] } };\n\nexport function verifyThat(fn: MockedFunction) {\n return {\n calledTimes: (times: number) => {\n assertEqual(fn.mock?.calls?.length, times);\n },\n notCalled: () => {\n assertEqual(fn?.mock?.calls?.length, 0);\n },\n called: () => {\n assertTrue(\n fn.mock?.calls.length !== undefined && fn.mock.calls.length > 0,\n );\n },\n calledWith: (...args: unknown[]) => {\n assertTrue(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length >= 1 &&\n fn.mock.calls.some((call) => deepEquals(call.arguments, args)),\n );\n },\n calledOnceWith: (...args: unknown[]) => {\n assertTrue(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length === 1 &&\n fn.mock.calls.some((call) => deepEquals(call.arguments, args)),\n );\n },\n calledWithArgumentMatching: (...matches: ArgumentMatcher[]) => {\n assertTrue(\n fn.mock?.calls.length !== undefined && fn.mock.calls.length >= 1,\n );\n assertTrue(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length >= 1 &&\n fn.mock.calls.some(\n (call) =>\n call.arguments &&\n call.arguments.length >= matches.length &&\n matches.every((match, index) => match(call.arguments[index])),\n ),\n );\n },\n notCalledWithArgumentMatching: (...matches: ArgumentMatcher[]) => {\n assertFalse(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length >= 1 &&\n fn.mock.calls[0]!.arguments &&\n fn.mock.calls[0]!.arguments.length >= matches.length &&\n matches.every((match, index) =>\n match(fn.mock!.calls[0]!.arguments[index]),\n ),\n );\n },\n };\n}\n\nexport const assertThatArray = <T>(array: T[]) => {\n return {\n isEmpty: () => assertEqual(array.length, 0),\n isNotEmpty: () => assertNotEqual(array.length, 0),\n hasSize: (length: number) => assertEqual(array.length, length),\n containsElements: (...other: T[]) => {\n assertTrue(other.every((ts) => other.some((o) => deepEquals(ts, o))));\n },\n containsExactlyInAnyOrder: (...other: T[]) => {\n assertEqual(array.length, other.length);\n assertTrue(array.every((ts) => other.some((o) => deepEquals(ts, o))));\n },\n containsExactlyInAnyOrderElementsOf: (other: T[]) => {\n assertEqual(array.length, other.length);\n assertTrue(array.every((ts) => other.some((o) => deepEquals(ts, o))));\n },\n containsExactlyElementsOf: (other: T[]) => {\n assertEqual(array.length, other.length);\n for (let i = 0; i < array.length; i++) {\n assertTrue(deepEquals(array[i], other[i]));\n }\n },\n containsExactly: (elem: T) => {\n assertEqual(array.length, 1);\n assertTrue(deepEquals(array[0], elem));\n },\n contains: (elem: T) => {\n assertTrue(array.some((a) => deepEquals(a, elem)));\n },\n containsOnlyOnceElementsOf: (other: T[]) => {\n assertTrue(\n other\n .map((o) => array.filter((a) => deepEquals(a, o)).length)\n .filter((a) => a === 1).length === other.length,\n );\n },\n containsAnyOf: (...other: T[]) => {\n assertTrue(array.some((a) => other.some((o) => deepEquals(a, o))));\n },\n allMatch: (matches: (item: T) => boolean) => {\n assertTrue(array.every(matches));\n },\n anyMatches: (matches: (item: T) => boolean) => {\n assertTrue(array.some(matches));\n },\n allMatchAsync: async (\n matches: (item: T) => Promise<boolean>,\n ): Promise<void> => {\n for (const item of array) {\n assertTrue(await matches(item));\n }\n },\n };\n};\n","import { ValidationError } from '../errors';\n\nexport const enum ValidationErrors {\n NOT_A_NONEMPTY_STRING = 'NOT_A_NONEMPTY_STRING',\n NOT_A_POSITIVE_NUMBER = 'NOT_A_POSITIVE_NUMBER',\n NOT_AN_UNSIGNED_BIGINT = 'NOT_AN_UNSIGNED_BIGINT',\n}\n\nexport const isNumber = (val: unknown): val is number =>\n typeof val === 'number' && val === val;\n\nexport const isString = (val: unknown): val is string =>\n typeof val === 'string';\n\nexport const assertNotEmptyString = (value: unknown): string => {\n if (!isString(value) || value.length === 0) {\n throw new ValidationError(ValidationErrors.NOT_A_NONEMPTY_STRING);\n }\n return value;\n};\n\nexport const assertPositiveNumber = (value: unknown): number => {\n if (!isNumber(value) || value <= 0) {\n throw new ValidationError(ValidationErrors.NOT_A_POSITIVE_NUMBER);\n }\n return value;\n};\n\nexport const assertUnsignedBigInt = (value: string): bigint => {\n const number = BigInt(value);\n if (number < 0) {\n throw new ValidationError(ValidationErrors.NOT_AN_UNSIGNED_BIGINT);\n }\n return number;\n};\n\nexport * from './dates';\n","import { isNumber, isString } from '../validation';\n\nexport type ErrorConstructor<ErrorType extends Error> = new (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ...args: any[]\n) => ErrorType;\n\nexport const isErrorConstructor = <ErrorType extends Error>(\n // eslint-disable-next-line @typescript-eslint/ban-types\n expect: Function,\n): expect is ErrorConstructor<ErrorType> => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return (\n typeof expect === 'function' &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect.prototype &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect.prototype.constructor === expect\n );\n};\n\nexport class EmmettError extends Error {\n public errorCode: number;\n\n constructor(\n options?: { errorCode: number; message?: string } | string | number,\n ) {\n const errorCode =\n options && typeof options === 'object' && 'errorCode' in options\n ? options.errorCode\n : isNumber(options)\n ? options\n : 500;\n const message =\n options && typeof options === 'object' && 'message' in options\n ? options.message\n : isString(options)\n ? options\n : `Error with status code '${errorCode}' ocurred during Emmett processing`;\n\n super(message);\n this.errorCode = errorCode;\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, EmmettError.prototype);\n }\n}\n\nexport class ConcurrencyError extends EmmettError {\n constructor(\n public current: string | undefined,\n public expected: string,\n message?: string,\n ) {\n super({\n errorCode: 412,\n message:\n message ??\n `Expected version ${expected.toString()} does not match current ${current?.toString()}`,\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, ConcurrencyError.prototype);\n }\n}\n\nexport class ValidationError extends EmmettError {\n constructor(message?: string) {\n super({\n errorCode: 400,\n message: message ?? `Validation Error ocurred during Emmett processing`,\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\nexport class IllegalStateError extends EmmettError {\n constructor(message?: string) {\n super({\n errorCode: 403,\n message: message ?? `Illegal State ocurred during Emmett processing`,\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, IllegalStateError.prototype);\n }\n}\n\nexport class NotFoundError extends EmmettError {\n constructor(options?: { id: string; type: string; message?: string }) {\n super({\n errorCode: 404,\n message:\n options?.message ??\n (options?.id\n ? options.type\n ? `${options.type} with ${options.id} was not found during Emmett processing`\n : `State with ${options.id} was not found during Emmett processing`\n : options?.type\n ? `${options.type} was not found during Emmett processing`\n : 'State was not found during Emmett processing'),\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, NotFoundError.prototype);\n }\n}\n","import { ValidationError } from '../errors';\n\nexport const formatDateToUtcYYYYMMDD = (date: Date) => {\n // Use the 'en-CA' locale which formats as 'yyyy-mm-dd'\n const formatter = new Intl.DateTimeFormat('en-CA', {\n timeZone: 'UTC',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n });\n\n // Format the date\n return formatter.format(date);\n};\n\n// Function to validate 'yyyy-mm-dd' format\nexport const isValidYYYYMMDD = (dateString: string) => {\n const regex = /^\\d{4}-\\d{2}-\\d{2}$/;\n return regex.test(dateString);\n};\n\nexport const parseDateFromUtcYYYYMMDD = (dateString: string) => {\n const date = new Date(dateString + 'T00:00:00Z');\n\n if (!isValidYYYYMMDD(dateString)) {\n throw new ValidationError('Invalid date format, must be yyyy-mm-dd');\n }\n\n if (isNaN(date.getTime())) {\n throw new ValidationError('Invalid date format');\n }\n\n return date;\n};\n","import type { DefaultRecord, Flavour } from './';\n\nexport type Event<\n EventType extends string = string,\n EventData extends DefaultRecord = DefaultRecord,\n EventMetaData extends DefaultRecord = DefaultRecord,\n> = Flavour<\n Readonly<{\n type: EventType;\n data: EventData;\n metadata?: EventMetaData;\n }>,\n 'Event'\n>;\n\nexport type EventTypeOf<T extends Event> = T['type'];\nexport type EventDataOf<T extends Event> = T['data'];\nexport type EventMetaDataOf<T extends Event> = T['metadata'];\n\nexport type CanHandle<T extends Event> = EventTypeOf<T>[];\n\nexport type CreateEventType<\n EventType extends string,\n EventData extends DefaultRecord,\n EventMetaData extends DefaultRecord | undefined,\n> = Readonly<{\n type: EventType;\n data: EventData;\n metadata?: EventMetaData;\n}>;\n\nexport const event = <EventType extends Event>(\n type: EventTypeOf<EventType>,\n data: EventDataOf<EventType>,\n metadata?: EventMetaDataOf<EventType>,\n): CreateEventType<\n EventTypeOf<EventType>,\n EventDataOf<EventType>,\n EventMetaDataOf<EventType>\n> => {\n return {\n type,\n data,\n metadata,\n };\n};\n\nexport type ReadEvent<\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadata = EventMetaDataOf<EventType> & ReadEventMetadata,\n> = CreateEventType<\n EventTypeOf<EventType>,\n EventDataOf<EventType>,\n EventMetaDataType\n> &\n EventType & { metadata: EventMetaDataType };\n\nexport type ReadEventMetadata = Readonly<{\n eventId: string;\n streamPosition: bigint;\n streamName: string;\n}>;\n\nexport type ReadEventMetadataWithGlobalPosition = ReadEventMetadata & {\n globalPosition: bigint;\n};\n","import type { CanHandle, DefaultRecord, Event, ReadEvent } from '../typing';\n\nexport type ProjectionHandlingType = 'inline' | 'async';\n\nexport type ProjectionHandler<\n EventType extends Event = Event,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> = (\n events: ReadEvent<EventType>[],\n context: ProjectionHandlerContext,\n) => Promise<void> | void;\n\nexport interface ProjectionDefinition<\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> {\n name?: string;\n canHandle: CanHandle<Event>;\n handle: ProjectionHandler<Event, ProjectionHandlerContext>;\n}\n\nexport interface TypedProjectionDefinition<\n EventType extends Event = Event,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> {\n name?: string;\n canHandle: CanHandle<EventType>;\n handle: ProjectionHandler<EventType, ProjectionHandlerContext>;\n}\n\nexport type ProjectionRegistration<\n HandlingType extends ProjectionHandlingType,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> = {\n type: HandlingType;\n projection: ProjectionDefinition<ProjectionHandlerContext>;\n};\n\nexport const projection = <\n EventType extends Event = Event,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n ProjectionDefintionType extends TypedProjectionDefinition<\n EventType,\n ProjectionHandlerContext\n > = ProjectionDefinition<ProjectionHandlerContext>,\n>(\n definition: ProjectionDefintionType,\n): ProjectionDefintionType => definition;\n\nexport const inlineProjections = <\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n ProjectionDefintionType extends\n ProjectionDefinition<ProjectionHandlerContext> = ProjectionDefinition<ProjectionHandlerContext>,\n>(\n definitions: ProjectionDefintionType[],\n): ProjectionRegistration<'inline', ProjectionHandlerContext>[] =>\n definitions.map((projection) => ({ type: 'inline', projection }));\n\nexport const asyncProjections = <\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n ProjectionDefintionType extends\n ProjectionDefinition<ProjectionHandlerContext> = ProjectionDefinition<ProjectionHandlerContext>,\n>(\n definitions: ProjectionDefintionType[],\n): ProjectionRegistration<'async', ProjectionHandlerContext>[] =>\n definitions.map((projection) => ({ type: 'async', projection }));\n\nexport const projections = {\n inline: inlineProjections,\n async: asyncProjections,\n};\n","import { ConcurrencyError } from '../errors';\nimport type { Flavour } from '../typing';\nimport type { DefaultStreamVersionType } from './eventStore';\n\nexport type ExpectedStreamVersion<VersionType = DefaultStreamVersionType> =\n | ExpectedStreamVersionWithValue<VersionType>\n | ExpectedStreamVersionGeneral;\n\nexport type ExpectedStreamVersionWithValue<\n VersionType = DefaultStreamVersionType,\n> = Flavour<VersionType, 'StreamVersion'>;\n\nexport type ExpectedStreamVersionGeneral = Flavour<\n 'STREAM_EXISTS' | 'STREAM_DOES_NOT_EXIST' | 'NO_CONCURRENCY_CHECK',\n 'StreamVersion'\n>;\n\nexport const STREAM_EXISTS = 'STREAM_EXISTS' as ExpectedStreamVersionGeneral;\nexport const STREAM_DOES_NOT_EXIST =\n 'STREAM_DOES_NOT_EXIST' as ExpectedStreamVersionGeneral;\nexport const NO_CONCURRENCY_CHECK =\n 'NO_CONCURRENCY_CHECK' as ExpectedStreamVersionGeneral;\n\nexport const matchesExpectedVersion = <\n StreamVersion = DefaultStreamVersionType,\n>(\n current: StreamVersion | undefined,\n expected: ExpectedStreamVersion<StreamVersion>,\n): boolean => {\n if (expected === NO_CONCURRENCY_CHECK) return true;\n\n if (expected == STREAM_DOES_NOT_EXIST) return current === undefined;\n\n if (expected == STREAM_EXISTS) return current !== undefined;\n\n return current === expected;\n};\n\nexport const assertExpectedVersionMatchesCurrent = <\n StreamVersion = DefaultStreamVersionType,\n>(\n current: StreamVersion | undefined,\n expected: ExpectedStreamVersion<StreamVersion> | undefined,\n): void => {\n expected ??= NO_CONCURRENCY_CHECK;\n\n if (!matchesExpectedVersion(current, expected))\n throw new ExpectedVersionConflictError(current, expected);\n};\n\nexport class ExpectedVersionConflictError<\n VersionType = DefaultStreamVersionType,\n> extends ConcurrencyError {\n constructor(\n current: VersionType | undefined,\n expected: ExpectedStreamVersion<VersionType>,\n ) {\n super(current?.toString(), expected?.toString());\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, ExpectedVersionConflictError.prototype);\n }\n}\n","import retry from 'async-retry';\nimport {\n ReadableStream,\n ReadableStreamDefaultReader,\n TransformStream,\n TransformStreamDefaultController,\n} from 'web-streams-polyfill';\nimport type { Decoder } from './decoders';\nimport { DefaultDecoder } from './decoders/composite';\n\nexport const restream = <\n Source = unknown,\n Transformed = Source,\n StreamType = object,\n>(\n createSourceStream: () => ReadableStream<StreamType>,\n transform: (input: Source) => Transformed = (source) =>\n source as unknown as Transformed,\n retryOptions: retry.Options = { forever: true, minTimeout: 25 },\n decoder: Decoder<StreamType, Source> = new DefaultDecoder<Source>(),\n): ReadableStream<Transformed> =>\n new TransformStream<Source, Transformed>({\n start(controller) {\n retry(\n () => onRestream(createSourceStream, controller, transform, decoder),\n retryOptions,\n ).catch((error) => {\n controller.error(error);\n });\n },\n }).readable;\n\nconst onRestream = async <StreamType, Source, Transformed = Source>(\n createSourceStream: () => ReadableStream<StreamType>,\n controller: TransformStreamDefaultController<Transformed>,\n transform: (input: Source) => Transformed,\n decoder: Decoder<StreamType, Source>,\n): Promise<void> => {\n const sourceStream = createSourceStream();\n const reader = sourceStream.getReader();\n try {\n let done: boolean;\n\n do {\n done = await restreamChunk(reader, controller, transform, decoder);\n } while (!done);\n } finally {\n reader.releaseLock();\n }\n};\n\nconst restreamChunk = async <StreamType, Source, Transformed = Source>(\n reader: ReadableStreamDefaultReader<StreamType>,\n controller: TransformStreamDefaultController<Transformed>,\n transform: (input: Source) => Transformed,\n decoder: Decoder<StreamType, Source>,\n): Promise<boolean> => {\n const { done: isDone, value } = await reader.read();\n\n if (value) decoder.addToBuffer(value);\n\n if (!isDone && !decoder.hasCompleteMessage()) return false;\n\n decodeAndTransform(decoder, transform, controller);\n\n if (isDone) {\n controller.terminate();\n }\n\n return isDone;\n};\n\nconst decodeAndTransform = <StreamType, Source, Transformed = Source>(\n decoder: Decoder<StreamType, Source>,\n transform: (input: Source) => Transformed,\n controller: TransformStreamDefaultController<Transformed>,\n) => {\n try {\n const decoded = decoder.decode();\n if (!decoded) return;\n\n const transformed = transform(decoded);\n controller.enqueue(transformed);\n } catch (error) {\n controller.error(new Error(`Decoding error: ${error?.toString()}`));\n }\n};\n","import { v4 as randomUUID } from 'uuid';\nimport type {\n Event,\n ReadEvent,\n ReadEventMetadataWithGlobalPosition,\n} from '../typing';\nimport {\n type AggregateStreamOptions,\n type AggregateStreamResult,\n type AppendToStreamOptions,\n type AppendToStreamResult,\n type DefaultStreamVersionType,\n type EventStore,\n type ReadStreamOptions,\n type ReadStreamResult,\n} from './eventStore';\nimport { assertExpectedVersionMatchesCurrent } from './expectedVersion';\n\nexport type EventHandler<E extends Event = Event> = (\n eventEnvelope: ReadEvent<E>,\n) => void;\n\nexport const getInMemoryEventStore = (): EventStore<\n DefaultStreamVersionType,\n ReadEventMetadataWithGlobalPosition\n> => {\n const streams = new Map<string, ReadEvent[]>();\n\n const getAllEventsCount = () => {\n return Array.from<ReadEvent[]>(streams.values())\n .map((s) => s.length)\n .reduce((p, c) => p + c, 0);\n };\n\n return {\n async aggregateStream<State, EventType extends Event>(\n streamName: string,\n options: AggregateStreamOptions<State, EventType>,\n ): Promise<AggregateStreamResult<State> | null> {\n const { evolve, initialState, read } = options;\n\n const result = await this.readStream<EventType>(streamName, read);\n\n if (!result) return null;\n\n const events = result?.events ?? [];\n\n return {\n currentStreamVersion: BigInt(events.length),\n state: events.reduce(evolve, initialState()),\n };\n },\n\n readStream: <EventType extends Event>(\n streamName: string,\n options?: ReadStreamOptions,\n ): Promise<\n ReadStreamResult<\n EventType,\n DefaultStreamVersionType,\n ReadEventMetadataWithGlobalPosition\n >\n > => {\n const events = streams.get(streamName);\n const currentStreamVersion = events ? BigInt(events.length) : undefined;\n\n assertExpectedVersionMatchesCurrent(\n currentStreamVersion,\n options?.expectedStreamVersion,\n );\n\n const from = Number(options && 'from' in options ? options.from : 0);\n const to = Number(\n options && 'to' in options\n ? options.to\n : options && 'maxCount' in options && options.maxCount\n ? options.from + options.maxCount\n : events?.length ?? 1,\n );\n\n const resultEvents =\n events && events.length > 0\n ? events\n .map(\n (e) =>\n e as ReadEvent<\n EventType,\n ReadEventMetadataWithGlobalPosition\n >,\n )\n .slice(from, to)\n : [];\n\n const result: ReadStreamResult<\n EventType,\n DefaultStreamVersionType,\n ReadEventMetadataWithGlobalPosition\n > =\n events && events.length > 0\n ? {\n currentStreamVersion: currentStreamVersion!,\n events: resultEvents,\n }\n : null;\n\n return Promise.resolve(result);\n },\n\n appendToStream: <EventType extends Event>(\n streamName: string,\n events: EventType[],\n options?: AppendToStreamOptions,\n ): Promise<AppendToStreamResult> => {\n const currentEvents = streams.get(streamName) ?? [];\n const currentStreamVersion =\n currentEvents.length > 0 ? BigInt(currentEvents.length) : undefined;\n\n assertExpectedVersionMatchesCurrent(\n currentStreamVersion,\n options?.expectedStreamVersion,\n );\n\n const eventEnvelopes: ReadEvent<\n EventType,\n ReadEventMetadataWithGlobalPosition\n >[] = events.map((event, index) => {\n return {\n ...event,\n metadata: {\n ...(event.metadata ?? {}),\n streamName,\n eventId: randomUUID(),\n streamPosition: BigInt(currentEvents.length + index + 1),\n globalPosition: BigInt(getAllEventsCount() + index + 1),\n },\n };\n });\n\n const positionOfLastEventInTheStream = BigInt(\n eventEnvelopes.slice(-1)[0]!.metadata.streamPosition,\n );\n\n streams.set(streamName, [...currentEvents, ...eventEnvelopes]);\n\n const result: AppendToStreamResult = {\n nextExpectedStreamVersion: positionOfLastEventInTheStream,\n };\n\n return Promise.resolve(result);\n },\n };\n};\n"],"mappings":"AAAO,IAAMA,EAAN,cAAyB,KAAM,CACpC,YAAYC,EAAc,CACxB,MAAM,iBAAiBA,CAAI,EAAE,CAC/B,CACF,EA0BaC,EAAa,CACxB,UAAW,CACTC,EACAC,IAEO,KAAK,UACVA,GAAS,IAAMA,EAAQ,IAAID,CAA6B,EAAIA,EAG5D,CAACE,EAAGC,IAAO,OAAOA,GAAM,SAAWA,EAAE,SAAS,EAAIA,CACpD,EAEF,MAAO,CACLL,EACAG,IACmB,CACnB,IAAMG,EAAkB,KAAK,MAAMN,EAAMG,GAAS,OAAO,EAEzD,GAAIA,GAAS,WAAa,CAACA,GAAS,UAAcG,CAAM,EACtD,MAAM,IAAIP,EAAWC,CAAI,EAE3B,OAAOG,GAAS,IACZA,EAAQ,IAAIG,CAA8B,EACzCA,CACP,CACF,ECvDO,IAAMC,EAAa,CAAIC,EAASC,IAAsB,CAC3D,GAAIC,EAAYF,CAAI,EAClB,OAAOA,EAAK,OAAOC,CAAK,EAG1B,GAAI,MAAM,QAAQD,CAAI,EACpB,OACE,MAAM,QAAQC,CAAK,GACnBD,EAAK,SAAWC,EAAM,QACtBD,EAAK,MAAM,CAACG,EAAKC,IAAUL,EAAWI,EAAKF,EAAMG,CAAK,CAAC,CAAC,EAI5D,GACE,OAAOJ,GAAS,UAChB,OAAOC,GAAU,UACjBD,IAAS,MACTC,IAAU,KAEV,OAAOD,IAASC,EAGlB,GAAI,MAAM,QAAQA,CAAK,EAAG,MAAO,GAEjC,IAAMI,EAAQ,OAAO,KAAKL,CAAI,EACxBM,EAAQ,OAAO,KAAKL,CAAK,EAE/B,GACEI,EAAM,SAAWC,EAAM,QACvB,CAACD,EAAM,MAAOE,GAAQD,EAAM,SAASC,CAAG,CAAC,EAEzC,MAAO,GAET,QAAWA,KAAOP,EAChB,GAAIA,IAAKO,CAAG,YAAa,UAAYN,EAAMM,CAAG,YAAa,WAIvD,CADYR,EAAWC,EAAKO,CAAG,EAAGN,EAAMM,CAAG,CAAC,EAE9C,MAAO,GAIX,MAAO,EACT,EAIaL,EAAkBF,GAE3BA,GACA,OAAOA,GAAS,UAChB,WAAYA,GACZ,OAAOA,EAAK,QAAc,WCjDvB,IAAMQ,EAAN,cAA6B,KAAM,CACxC,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,CACf,CACF,EAJO,IAoBMC,EAAeC,GAAqB,CAC/C,MAAM,IAAIC,EAAeD,GAAW,uCAAuC,CAC7E,EAtBO,IA+DME,EAAkB,CAC7BC,EACAC,EACAC,IACG,CACH,GAAI,CAACC,EAAWH,EAAQC,CAAQ,EAC9B,MAAM,IAAIG,EACRF,GACE;EAAYG,EAAW,UAAUJ,CAAQ,CAAC;;EAAsBI,EAAW,UAAUL,CAAM,CAAC,EAChG,CACJ,EA2BO,SAASM,EACdC,EACAC,EAC2B,CAC3B,GAAI,CAACD,EAAW,MAAM,IAAIE,EAAeD,GAAW,oBAAoB,CAC1E,CAEO,SAASE,EACdC,EACAH,EACkB,CAClB,GAAI,CAACG,EAAK,MAAM,IAAIF,EAAeD,GAAW,yBAAyB,CACzE,CAEO,SAASI,EACdC,EACAC,EACAN,EACM,CACN,GAAIK,IAAaC,EACf,MAAM,IAAIL,EACRD,GACE;YAAqCO,EAAW,UAAUF,CAAQ,CAAC;SAAYE,EAAW,UAAUD,CAAM,CAAC,EAC/G,CACJ,CAEO,SAASE,EACdL,EACAM,EACAT,EACM,CACN,GAAIG,IAAQM,EACV,MAAM,IAAIR,EACRD,GAAW,sBAAsBO,EAAW,UAAUJ,CAAG,CAAC,EAC5D,CACJ,CAEO,SAASO,EACdC,EACqB,CACrBH,EAAeG,EAAQ,IAAI,EAC3BT,EAASS,CAAM,CACjB,CAsFO,IAAMC,EAAsBC,IAC1B,CACL,QAAS,IAAMC,EAAYD,EAAM,OAAQ,CAAC,EAC1C,WAAY,IAAME,EAAeF,EAAM,OAAQ,CAAC,EAChD,QAAUG,GAAmBF,EAAYD,EAAM,OAAQG,CAAM,EAC7D,iBAAkB,IAAIC,IAAe,CACnCC,EAAWD,EAAM,MAAOE,GAAOF,EAAM,KAAMG,GAAMC,EAAWF,EAAIC,CAAC,CAAC,CAAC,CAAC,CACtE,EACA,0BAA2B,IAAIH,IAAe,CAC5CH,EAAYD,EAAM,OAAQI,EAAM,MAAM,EACtCC,EAAWL,EAAM,MAAOM,GAAOF,EAAM,KAAMG,GAAMC,EAAWF,EAAIC,CAAC,CAAC,CAAC,CAAC,CACtE,EACA,oCAAsCH,GAAe,CACnDH,EAAYD,EAAM,OAAQI,EAAM,MAAM,EACtCC,EAAWL,EAAM,MAAOM,GAAOF,EAAM,KAAMG,GAAMC,EAAWF,EAAIC,CAAC,CAAC,CAAC,CAAC,CACtE,EACA,0BAA4BH,GAAe,CACzCH,EAAYD,EAAM,OAAQI,EAAM,MAAM,EACtC,QAASK,EAAI,EAAGA,EAAIT,EAAM,OAAQS,IAChCJ,EAAWG,EAAWR,EAAMS,CAAC,EAAGL,EAAMK,CAAC,CAAC,CAAC,CAE7C,EACA,gBAAkBC,GAAY,CAC5BT,EAAYD,EAAM,OAAQ,CAAC,EAC3BK,EAAWG,EAAWR,EAAM,CAAC,EAAGU,CAAI,CAAC,CACvC,EACA,SAAWA,GAAY,CACrBL,EAAWL,EAAM,KAAMW,GAAMH,EAAWG,EAAGD,CAAI,CAAC,CAAC,CACnD,EACA,2BAA6BN,GAAe,CAC1CC,EACED,EACG,IAAKG,GAAMP,EAAM,OAAQW,GAAMH,EAAWG,EAAGJ,CAAC,CAAC,EAAE,MAAM,EACvD,OAAQI,GAAMA,IAAM,CAAC,EAAE,SAAWP,EAAM,MAC7C,CACF,EACA,cAAe,IAAIA,IAAe,CAChCC,EAAWL,EAAM,KAAMW,GAAMP,EAAM,KAAMG,GAAMC,EAAWG,EAAGJ,CAAC,CAAC,CAAC,CAAC,CACnE,EACA,SAAWK,GAAkC,CAC3CP,EAAWL,EAAM,MAAMY,CAAO,CAAC,CACjC,EACA,WAAaA,GAAkC,CAC7CP,EAAWL,EAAM,KAAKY,CAAO,CAAC,CAChC,EACA,cAAe,MACbA,GACkB,CAClB,QAAWC,KAAQb,EACjBK,EAAW,MAAMO,EAAQC,CAAI,CAAC,CAElC,CACF,GC1RK,IAAWC,GAAAA,IAChBA,EAAA,sBAAwB,wBACxBA,EAAA,sBAAwB,wBACxBA,EAAA,uBAAyB,yBAHTA,IAAAA,GAAA,CAAA,CAAA,EAMLC,EAAYC,GACvB,OAAOA,GAAQ,UAAYA,IAAQA,EAExBC,EAAYD,GACvB,OAAOA,GAAQ,SCLV,IAAME,EAEXC,GAIE,OAAOA,GAAW,YAElBA,EAAO,WAEPA,EAAO,UAAU,cAAgBA,EAIxBC,EAAN,MAAMC,UAAoB,KAAM,CAC9B,UAEP,YACEC,EACA,CACA,IAAMC,EACJD,GAAW,OAAOA,GAAY,UAAY,cAAeA,EACrDA,EAAQ,UACRE,EAASF,CAAO,EACdA,EACA,IACFG,EACJH,GAAW,OAAOA,GAAY,UAAY,YAAaA,EACnDA,EAAQ,QACRI,EAASJ,CAAO,EACdA,EACA,2BAA2BC,CAAS,qCAE5C,MAAME,CAAO,EACb,KAAK,UAAYF,EAGjB,OAAO,eAAe,KAAMF,EAAY,SAAS,CACnD,CACF,EAEaM,EAAN,MAAMC,UAAyBR,CAAY,CAChD,YACSS,EACAC,EACPL,EACA,CACA,MAAM,CACJ,UAAW,IACX,QACEA,GACA,oBAAoBK,EAAS,SAAS,CAAC,2BAA2BD,GAAS,SAAS,CAAC,EACzF,CAAC,EATM,KAAA,QAAAA,EACA,KAAA,SAAAC,EAWP,OAAO,eAAe,KAAMF,EAAiB,SAAS,CACxD,CACF,EEjCO,IAAMG,EAAQ,CACnBC,EACAC,EACAC,KAMO,CACL,KAAAF,EACA,KAAAC,EACA,SAAAC,CACF,GCPK,IAAMC,EAQXC,GAC4BA,EC7BvB,IAAMC,EAAgB,gBAChBC,EACX,wBACWC,EACX,uBAJK,IAiCMC,EAAN,MAAMC,UAEHC,CAAiB,CACzB,YACEC,EACAC,EACA,CACA,MAAMD,GAAS,SAAS,EAAGC,GAAU,SAAS,CAAC,EAG/C,OAAO,eAAe,KAAMH,EAA6B,SAAS,CACpE,CACF,EC9DA,OAAOI,OAAW,cAClB,OAGE,mBAAAC,OAEK,uBCNP,OAAS,MAAMC,OAAkB","names":["ParseError","text","JSONParser","value","options","_","v","parsed","deepEquals","left","right","isEquatable","val","index","keys1","keys2","key","AssertionError","message","assertFails","message","AssertionError","assertDeepEqual","actual","expected","message","deepEquals","AssertionError","JSONParser","assertTrue","condition","message","AssertionError","assertOk","obj","assertEqual","expected","actual","JSONParser","assertNotEqual","other","assertIsNotNull","result","assertThatArray","array","assertEqual","assertNotEqual","length","other","assertTrue","ts","o","deepEquals","i","elem","a","matches","item","ValidationErrors","isNumber","val","isString","isErrorConstructor","expect","EmmettError","_EmmettError","options","errorCode","isNumber","message","isString","ConcurrencyError","_ConcurrencyError","current","expected","event","type","data","metadata","projection","definition","STREAM_EXISTS","STREAM_DOES_NOT_EXIST","NO_CONCURRENCY_CHECK","ExpectedVersionConflictError","_ExpectedVersionConflictError","ConcurrencyError","current","expected","retry","TransformStream","randomUUID"]}
|
|
1
|
+
{"version":3,"sources":["../../emmett/src/serialization/json/JSONParser.ts","../../emmett/src/utils/deepEquals.ts","../../emmett/src/testing/assertions.ts","../../emmett/src/validation/index.ts","../../emmett/src/errors/index.ts","../../emmett/src/validation/dates.ts","../../emmett/src/typing/event.ts","../../emmett/src/projections/index.ts","../../emmett/src/eventStore/expectedVersion.ts","../../emmett/src/streaming/restream.ts","../../emmett/src/eventStore/inMemoryEventStore.ts"],"sourcesContent":["export class ParseError extends Error {\n constructor(text: string) {\n super(`Cannot parse! ${text}`);\n }\n}\n\nexport type Mapper<From, To = From> =\n | ((value: unknown) => To)\n | ((value: Partial<From>) => To)\n | ((value: From) => To)\n | ((value: Partial<To>) => To)\n | ((value: To) => To)\n | ((value: Partial<To | From>) => To)\n | ((value: To | From) => To);\n\nexport type MapperArgs<From, To = From> = Partial<From> &\n From &\n Partial<To> &\n To;\n\nexport type ParseOptions<From, To = From> = {\n reviver?: (key: string, value: unknown) => unknown;\n map?: Mapper<From, To>;\n typeCheck?: <To>(value: unknown) => value is To;\n};\n\nexport type StringifyOptions<From, To = From> = {\n map?: Mapper<From, To>;\n};\n\nexport const JSONParser = {\n stringify: <From, To = From>(\n value: From,\n options?: StringifyOptions<From, To>,\n ) => {\n return JSON.stringify(\n options?.map ? options.map(value as MapperArgs<From, To>) : value,\n //TODO: Consider adding support to DateTime and adding specific format to mark that's a bigint\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n (_, v) => (typeof v === 'bigint' ? v.toString() : v),\n );\n },\n parse: <From, To = From>(\n text: string,\n options?: ParseOptions<From, To>,\n ): To | undefined => {\n const parsed: unknown = JSON.parse(text, options?.reviver);\n\n if (options?.typeCheck && !options?.typeCheck<To>(parsed))\n throw new ParseError(text);\n\n return options?.map\n ? options.map(parsed as MapperArgs<From, To>)\n : (parsed as To | undefined);\n },\n};\n","export const deepEquals = <T>(left: T, right: T): boolean => {\n if (isEquatable(left)) {\n return left.equals(right);\n }\n\n if (Array.isArray(left)) {\n return (\n Array.isArray(right) &&\n left.length === right.length &&\n left.every((val, index) => deepEquals(val, right[index]))\n );\n }\n\n if (\n typeof left !== 'object' ||\n typeof right !== 'object' ||\n left === null ||\n right === null\n ) {\n return left === right;\n }\n\n if (Array.isArray(right)) return false;\n\n const keys1 = Object.keys(left);\n const keys2 = Object.keys(right);\n\n if (\n keys1.length !== keys2.length ||\n !keys1.every((key) => keys2.includes(key))\n )\n return false;\n\n for (const key in left) {\n if (left[key] instanceof Function && right[key] instanceof Function)\n continue;\n\n const isEqual = deepEquals(left[key], right[key]);\n if (!isEqual) {\n return false;\n }\n }\n\n return true;\n};\n\nexport type Equatable<T> = { equals: (right: T) => boolean } & T;\n\nexport const isEquatable = <T>(left: T): left is Equatable<T> => {\n return (\n left &&\n typeof left === 'object' &&\n 'equals' in left &&\n typeof left['equals'] === 'function'\n );\n};\n","import { JSONParser } from '../serialization';\nimport type { DefaultRecord } from '../typing';\nimport { deepEquals } from '../utils';\n\nexport class AssertionError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\nexport const isSubset = (superObj: unknown, subObj: unknown): boolean => {\n const sup = superObj as DefaultRecord;\n const sub = subObj as DefaultRecord;\n\n assertOk(sup);\n assertOk(sub);\n\n return Object.keys(sub).every((ele: string) => {\n if (typeof sub[ele] == 'object') {\n return isSubset(sup[ele], sub[ele]);\n }\n return sub[ele] === sup[ele];\n });\n};\n\nexport const assertFails = (message?: string) => {\n throw new AssertionError(message ?? 'That should not ever happened, right?');\n};\n\nexport const assertThrowsAsync = async <TError extends Error>(\n fun: () => Promise<void>,\n errorCheck?: (error: Error) => boolean,\n): Promise<TError> => {\n try {\n await fun();\n throw new AssertionError(\"Function didn't throw expected error\");\n } catch (error) {\n const typedError = error as TError;\n if (errorCheck) assertTrue(errorCheck(typedError));\n return typedError;\n }\n};\n\nexport const assertThrows = <TError extends Error>(\n fun: () => void,\n errorCheck?: (error: Error) => boolean,\n): TError => {\n try {\n fun();\n throw new AssertionError(\"Function didn't throw expected error\");\n } catch (error) {\n const typedError = error as TError;\n if (errorCheck) assertTrue(errorCheck(typedError));\n return typedError;\n }\n};\nexport const assertMatches = (\n actual: unknown,\n expected: unknown,\n message?: string,\n) => {\n if (!isSubset(actual, expected))\n throw new AssertionError(\n message ??\n `subObj:\\n${JSONParser.stringify(expected)}\\nis not subset of\\n${JSONParser.stringify(actual)}`,\n );\n};\n\nexport const assertDeepEqual = <T = unknown>(\n actual: T,\n expected: T,\n message?: string,\n) => {\n if (!deepEquals(actual, expected))\n throw new AssertionError(\n message ??\n `subObj:\\n${JSONParser.stringify(expected)}\\nis not equal to\\n${JSONParser.stringify(actual)}`,\n );\n};\n\nexport const assertNotDeepEqual = <T = unknown>(\n actual: T,\n expected: T,\n message?: string,\n) => {\n if (deepEquals(actual, expected))\n throw new AssertionError(\n message ??\n `subObj:\\n${JSONParser.stringify(expected)}\\nis equals to\\n${JSONParser.stringify(actual)}`,\n );\n};\n\nexport const assertThat = <T>(item: T) => {\n return {\n isEqualTo: (other: T) => assertTrue(deepEquals(item, other)),\n };\n};\n\nexport function assertFalse(\n condition: boolean,\n message?: string,\n): asserts condition is false {\n if (condition) throw new AssertionError(message ?? `Condition is false`);\n}\n\nexport function assertTrue(\n condition: boolean,\n message?: string,\n): asserts condition is true {\n if (!condition) throw new AssertionError(message ?? `Condition is false`);\n}\n\nexport function assertOk<T>(\n obj: T | null | undefined,\n message?: string,\n): asserts obj is T {\n if (!obj) throw new AssertionError(message ?? `Condition is not truthy`);\n}\n\nexport function assertEqual<T>(\n expected: T | null | undefined,\n actual: T | null | undefined,\n message?: string,\n): void {\n if (expected !== actual)\n throw new AssertionError(\n message ??\n `Objects are not equal:\\nExpected: ${JSONParser.stringify(expected)}\\nActual:${JSONParser.stringify(actual)}`,\n );\n}\n\nexport function assertNotEqual<T>(\n obj: T | null | undefined,\n other: T | null | undefined,\n message?: string,\n): void {\n if (obj === other)\n throw new AssertionError(\n message ?? `Objects are equal: ${JSONParser.stringify(obj)}`,\n );\n}\n\nexport function assertIsNotNull<T extends object | bigint>(\n result: T | null,\n): asserts result is T {\n assertNotEqual(result, null);\n assertOk(result);\n}\n\nexport function assertIsNull<T extends object>(\n result: T | null,\n): asserts result is null {\n assertEqual(result, null);\n}\n\ntype Call = {\n arguments: unknown[];\n result: unknown;\n target: unknown;\n this: unknown;\n};\n\nexport type ArgumentMatcher = (arg: unknown) => boolean;\n\nexport const argValue =\n <T>(value: T): ArgumentMatcher =>\n (arg) =>\n deepEquals(arg, value);\n\nexport const argMatches =\n <T>(matches: (arg: T) => boolean): ArgumentMatcher =>\n (arg) =>\n matches(arg as T);\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport type MockedFunction = Function & { mock?: { calls: Call[] } };\n\nexport function verifyThat(fn: MockedFunction) {\n return {\n calledTimes: (times: number) => {\n assertEqual(fn.mock?.calls?.length, times);\n },\n notCalled: () => {\n assertEqual(fn?.mock?.calls?.length, 0);\n },\n called: () => {\n assertTrue(\n fn.mock?.calls.length !== undefined && fn.mock.calls.length > 0,\n );\n },\n calledWith: (...args: unknown[]) => {\n assertTrue(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length >= 1 &&\n fn.mock.calls.some((call) => deepEquals(call.arguments, args)),\n );\n },\n calledOnceWith: (...args: unknown[]) => {\n assertTrue(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length === 1 &&\n fn.mock.calls.some((call) => deepEquals(call.arguments, args)),\n );\n },\n calledWithArgumentMatching: (...matches: ArgumentMatcher[]) => {\n assertTrue(\n fn.mock?.calls.length !== undefined && fn.mock.calls.length >= 1,\n );\n assertTrue(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length >= 1 &&\n fn.mock.calls.some(\n (call) =>\n call.arguments &&\n call.arguments.length >= matches.length &&\n matches.every((match, index) => match(call.arguments[index])),\n ),\n );\n },\n notCalledWithArgumentMatching: (...matches: ArgumentMatcher[]) => {\n assertFalse(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length >= 1 &&\n fn.mock.calls[0]!.arguments &&\n fn.mock.calls[0]!.arguments.length >= matches.length &&\n matches.every((match, index) =>\n match(fn.mock!.calls[0]!.arguments[index]),\n ),\n );\n },\n };\n}\n\nexport const assertThatArray = <T>(array: T[]) => {\n return {\n isEmpty: () => assertEqual(array.length, 0),\n isNotEmpty: () => assertNotEqual(array.length, 0),\n hasSize: (length: number) => assertEqual(array.length, length),\n containsElements: (...other: T[]) => {\n assertTrue(other.every((ts) => other.some((o) => deepEquals(ts, o))));\n },\n containsExactlyInAnyOrder: (...other: T[]) => {\n assertEqual(array.length, other.length);\n assertTrue(array.every((ts) => other.some((o) => deepEquals(ts, o))));\n },\n containsExactlyInAnyOrderElementsOf: (other: T[]) => {\n assertEqual(array.length, other.length);\n assertTrue(array.every((ts) => other.some((o) => deepEquals(ts, o))));\n },\n containsExactlyElementsOf: (other: T[]) => {\n assertEqual(array.length, other.length);\n for (let i = 0; i < array.length; i++) {\n assertTrue(deepEquals(array[i], other[i]));\n }\n },\n containsExactly: (elem: T) => {\n assertEqual(array.length, 1);\n assertTrue(deepEquals(array[0], elem));\n },\n contains: (elem: T) => {\n assertTrue(array.some((a) => deepEquals(a, elem)));\n },\n containsOnlyOnceElementsOf: (other: T[]) => {\n assertTrue(\n other\n .map((o) => array.filter((a) => deepEquals(a, o)).length)\n .filter((a) => a === 1).length === other.length,\n );\n },\n containsAnyOf: (...other: T[]) => {\n assertTrue(array.some((a) => other.some((o) => deepEquals(a, o))));\n },\n allMatch: (matches: (item: T) => boolean) => {\n assertTrue(array.every(matches));\n },\n anyMatches: (matches: (item: T) => boolean) => {\n assertTrue(array.some(matches));\n },\n allMatchAsync: async (\n matches: (item: T) => Promise<boolean>,\n ): Promise<void> => {\n for (const item of array) {\n assertTrue(await matches(item));\n }\n },\n };\n};\n","import { ValidationError } from '../errors';\n\nexport const enum ValidationErrors {\n NOT_A_NONEMPTY_STRING = 'NOT_A_NONEMPTY_STRING',\n NOT_A_POSITIVE_NUMBER = 'NOT_A_POSITIVE_NUMBER',\n NOT_AN_UNSIGNED_BIGINT = 'NOT_AN_UNSIGNED_BIGINT',\n}\n\nexport const isNumber = (val: unknown): val is number =>\n typeof val === 'number' && val === val;\n\nexport const isString = (val: unknown): val is string =>\n typeof val === 'string';\n\nexport const assertNotEmptyString = (value: unknown): string => {\n if (!isString(value) || value.length === 0) {\n throw new ValidationError(ValidationErrors.NOT_A_NONEMPTY_STRING);\n }\n return value;\n};\n\nexport const assertPositiveNumber = (value: unknown): number => {\n if (!isNumber(value) || value <= 0) {\n throw new ValidationError(ValidationErrors.NOT_A_POSITIVE_NUMBER);\n }\n return value;\n};\n\nexport const assertUnsignedBigInt = (value: string): bigint => {\n const number = BigInt(value);\n if (number < 0) {\n throw new ValidationError(ValidationErrors.NOT_AN_UNSIGNED_BIGINT);\n }\n return number;\n};\n\nexport * from './dates';\n","import { isNumber, isString } from '../validation';\n\nexport type ErrorConstructor<ErrorType extends Error> = new (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ...args: any[]\n) => ErrorType;\n\nexport const isErrorConstructor = <ErrorType extends Error>(\n // eslint-disable-next-line @typescript-eslint/ban-types\n expect: Function,\n): expect is ErrorConstructor<ErrorType> => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return (\n typeof expect === 'function' &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect.prototype &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect.prototype.constructor === expect\n );\n};\n\nexport class EmmettError extends Error {\n public errorCode: number;\n\n constructor(\n options?: { errorCode: number; message?: string } | string | number,\n ) {\n const errorCode =\n options && typeof options === 'object' && 'errorCode' in options\n ? options.errorCode\n : isNumber(options)\n ? options\n : 500;\n const message =\n options && typeof options === 'object' && 'message' in options\n ? options.message\n : isString(options)\n ? options\n : `Error with status code '${errorCode}' ocurred during Emmett processing`;\n\n super(message);\n this.errorCode = errorCode;\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, EmmettError.prototype);\n }\n}\n\nexport class ConcurrencyError extends EmmettError {\n constructor(\n public current: string | undefined,\n public expected: string,\n message?: string,\n ) {\n super({\n errorCode: 412,\n message:\n message ??\n `Expected version ${expected.toString()} does not match current ${current?.toString()}`,\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, ConcurrencyError.prototype);\n }\n}\n\nexport class ValidationError extends EmmettError {\n constructor(message?: string) {\n super({\n errorCode: 400,\n message: message ?? `Validation Error ocurred during Emmett processing`,\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\nexport class IllegalStateError extends EmmettError {\n constructor(message?: string) {\n super({\n errorCode: 403,\n message: message ?? `Illegal State ocurred during Emmett processing`,\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, IllegalStateError.prototype);\n }\n}\n\nexport class NotFoundError extends EmmettError {\n constructor(options?: { id: string; type: string; message?: string }) {\n super({\n errorCode: 404,\n message:\n options?.message ??\n (options?.id\n ? options.type\n ? `${options.type} with ${options.id} was not found during Emmett processing`\n : `State with ${options.id} was not found during Emmett processing`\n : options?.type\n ? `${options.type} was not found during Emmett processing`\n : 'State was not found during Emmett processing'),\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, NotFoundError.prototype);\n }\n}\n","import { ValidationError } from '../errors';\n\nexport const formatDateToUtcYYYYMMDD = (date: Date) => {\n // Use the 'en-CA' locale which formats as 'yyyy-mm-dd'\n const formatter = new Intl.DateTimeFormat('en-CA', {\n timeZone: 'UTC',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n });\n\n // Format the date\n return formatter.format(date);\n};\n\n// Function to validate 'yyyy-mm-dd' format\nexport const isValidYYYYMMDD = (dateString: string) => {\n const regex = /^\\d{4}-\\d{2}-\\d{2}$/;\n return regex.test(dateString);\n};\n\nexport const parseDateFromUtcYYYYMMDD = (dateString: string) => {\n const date = new Date(dateString + 'T00:00:00Z');\n\n if (!isValidYYYYMMDD(dateString)) {\n throw new ValidationError('Invalid date format, must be yyyy-mm-dd');\n }\n\n if (isNaN(date.getTime())) {\n throw new ValidationError('Invalid date format');\n }\n\n return date;\n};\n","import type { DefaultRecord, Flavour } from './';\n\nexport type Event<\n EventType extends string = string,\n EventData extends DefaultRecord = DefaultRecord,\n EventMetaData extends DefaultRecord = DefaultRecord,\n> = Flavour<\n Readonly<{\n type: EventType;\n data: EventData;\n metadata?: EventMetaData;\n }>,\n 'Event'\n>;\n\nexport type EventTypeOf<T extends Event> = T['type'];\nexport type EventDataOf<T extends Event> = T['data'];\nexport type EventMetaDataOf<T extends Event> = T['metadata'];\n\nexport type CanHandle<T extends Event> = EventTypeOf<T>[];\n\nexport type CreateEventType<\n EventType extends string,\n EventData extends DefaultRecord,\n EventMetaData extends DefaultRecord | undefined,\n> = Readonly<{\n type: EventType;\n data: EventData;\n metadata?: EventMetaData;\n}>;\n\nexport const event = <EventType extends Event>(\n type: EventTypeOf<EventType>,\n data: EventDataOf<EventType>,\n metadata?: EventMetaDataOf<EventType>,\n): CreateEventType<\n EventTypeOf<EventType>,\n EventDataOf<EventType>,\n EventMetaDataOf<EventType>\n> => {\n return {\n type,\n data,\n metadata,\n };\n};\n\nexport type ReadEvent<\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadata = EventMetaDataOf<EventType> & ReadEventMetadata,\n> = CreateEventType<\n EventTypeOf<EventType>,\n EventDataOf<EventType>,\n EventMetaDataType\n> &\n EventType & { metadata: EventMetaDataType };\n\nexport type ReadEventMetadata = Readonly<{\n eventId: string;\n streamPosition: bigint;\n streamName: string;\n}>;\n\nexport type ReadEventMetadataWithGlobalPosition = ReadEventMetadata & {\n globalPosition: bigint;\n};\n","import type {\n CanHandle,\n DefaultRecord,\n Event,\n EventMetaDataOf,\n ReadEvent,\n ReadEventMetadata,\n} from '../typing';\n\nexport type ProjectionHandlingType = 'inline' | 'async';\n\nexport type ProjectionHandler<\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadata = EventMetaDataOf<EventType> & ReadEventMetadata,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> = (\n events: ReadEvent<EventType, EventMetaDataType>[],\n context: ProjectionHandlerContext,\n) => Promise<void> | void;\n\nexport interface ProjectionDefinition<\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> {\n name?: string;\n canHandle: CanHandle<Event>;\n handle: ProjectionHandler<Event, ReadEventMetadata, ProjectionHandlerContext>;\n}\n\nexport interface TypedProjectionDefinition<\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadata = EventMetaDataOf<EventType> & ReadEventMetadata,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> {\n name?: string;\n canHandle: CanHandle<EventType>;\n handle: ProjectionHandler<\n EventType,\n EventMetaDataType,\n ProjectionHandlerContext\n >;\n}\n\nexport type ProjectionRegistration<\n HandlingType extends ProjectionHandlingType,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> = {\n type: HandlingType;\n projection: ProjectionDefinition<ProjectionHandlerContext>;\n};\n\nexport const projection = <\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadata = EventMetaDataOf<EventType> & ReadEventMetadata,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n ProjectionDefintionType extends TypedProjectionDefinition<\n EventType,\n EventMetaDataType,\n ProjectionHandlerContext\n > = ProjectionDefinition<ProjectionHandlerContext>,\n>(\n definition: ProjectionDefintionType,\n): ProjectionDefintionType => definition;\n\nexport const inlineProjections = <\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n ProjectionDefintionType extends\n ProjectionDefinition<ProjectionHandlerContext> = ProjectionDefinition<ProjectionHandlerContext>,\n>(\n definitions: ProjectionDefintionType[],\n): ProjectionRegistration<'inline', ProjectionHandlerContext>[] =>\n definitions.map((projection) => ({ type: 'inline', projection }));\n\nexport const asyncProjections = <\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n ProjectionDefintionType extends\n ProjectionDefinition<ProjectionHandlerContext> = ProjectionDefinition<ProjectionHandlerContext>,\n>(\n definitions: ProjectionDefintionType[],\n): ProjectionRegistration<'async', ProjectionHandlerContext>[] =>\n definitions.map((projection) => ({ type: 'async', projection }));\n\nexport const projections = {\n inline: inlineProjections,\n async: asyncProjections,\n};\n","import { ConcurrencyError } from '../errors';\nimport type { Flavour } from '../typing';\nimport type { DefaultStreamVersionType } from './eventStore';\n\nexport type ExpectedStreamVersion<VersionType = DefaultStreamVersionType> =\n | ExpectedStreamVersionWithValue<VersionType>\n | ExpectedStreamVersionGeneral;\n\nexport type ExpectedStreamVersionWithValue<\n VersionType = DefaultStreamVersionType,\n> = Flavour<VersionType, 'StreamVersion'>;\n\nexport type ExpectedStreamVersionGeneral = Flavour<\n 'STREAM_EXISTS' | 'STREAM_DOES_NOT_EXIST' | 'NO_CONCURRENCY_CHECK',\n 'StreamVersion'\n>;\n\nexport const STREAM_EXISTS = 'STREAM_EXISTS' as ExpectedStreamVersionGeneral;\nexport const STREAM_DOES_NOT_EXIST =\n 'STREAM_DOES_NOT_EXIST' as ExpectedStreamVersionGeneral;\nexport const NO_CONCURRENCY_CHECK =\n 'NO_CONCURRENCY_CHECK' as ExpectedStreamVersionGeneral;\n\nexport const matchesExpectedVersion = <\n StreamVersion = DefaultStreamVersionType,\n>(\n current: StreamVersion | undefined,\n expected: ExpectedStreamVersion<StreamVersion>,\n): boolean => {\n if (expected === NO_CONCURRENCY_CHECK) return true;\n\n if (expected == STREAM_DOES_NOT_EXIST) return current === undefined;\n\n if (expected == STREAM_EXISTS) return current !== undefined;\n\n return current === expected;\n};\n\nexport const assertExpectedVersionMatchesCurrent = <\n StreamVersion = DefaultStreamVersionType,\n>(\n current: StreamVersion | undefined,\n expected: ExpectedStreamVersion<StreamVersion> | undefined,\n): void => {\n expected ??= NO_CONCURRENCY_CHECK;\n\n if (!matchesExpectedVersion(current, expected))\n throw new ExpectedVersionConflictError(current, expected);\n};\n\nexport class ExpectedVersionConflictError<\n VersionType = DefaultStreamVersionType,\n> extends ConcurrencyError {\n constructor(\n current: VersionType | undefined,\n expected: ExpectedStreamVersion<VersionType>,\n ) {\n super(current?.toString(), expected?.toString());\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, ExpectedVersionConflictError.prototype);\n }\n}\n","import retry from 'async-retry';\nimport {\n ReadableStream,\n ReadableStreamDefaultReader,\n TransformStream,\n TransformStreamDefaultController,\n} from 'web-streams-polyfill';\nimport type { Decoder } from './decoders';\nimport { DefaultDecoder } from './decoders/composite';\n\nexport const restream = <\n Source = unknown,\n Transformed = Source,\n StreamType = object,\n>(\n createSourceStream: () => ReadableStream<StreamType>,\n transform: (input: Source) => Transformed = (source) =>\n source as unknown as Transformed,\n retryOptions: retry.Options = { forever: true, minTimeout: 25 },\n decoder: Decoder<StreamType, Source> = new DefaultDecoder<Source>(),\n): ReadableStream<Transformed> =>\n new TransformStream<Source, Transformed>({\n start(controller) {\n retry(\n () => onRestream(createSourceStream, controller, transform, decoder),\n retryOptions,\n ).catch((error) => {\n controller.error(error);\n });\n },\n }).readable;\n\nconst onRestream = async <StreamType, Source, Transformed = Source>(\n createSourceStream: () => ReadableStream<StreamType>,\n controller: TransformStreamDefaultController<Transformed>,\n transform: (input: Source) => Transformed,\n decoder: Decoder<StreamType, Source>,\n): Promise<void> => {\n const sourceStream = createSourceStream();\n const reader = sourceStream.getReader();\n try {\n let done: boolean;\n\n do {\n done = await restreamChunk(reader, controller, transform, decoder);\n } while (!done);\n } finally {\n reader.releaseLock();\n }\n};\n\nconst restreamChunk = async <StreamType, Source, Transformed = Source>(\n reader: ReadableStreamDefaultReader<StreamType>,\n controller: TransformStreamDefaultController<Transformed>,\n transform: (input: Source) => Transformed,\n decoder: Decoder<StreamType, Source>,\n): Promise<boolean> => {\n const { done: isDone, value } = await reader.read();\n\n if (value) decoder.addToBuffer(value);\n\n if (!isDone && !decoder.hasCompleteMessage()) return false;\n\n decodeAndTransform(decoder, transform, controller);\n\n if (isDone) {\n controller.terminate();\n }\n\n return isDone;\n};\n\nconst decodeAndTransform = <StreamType, Source, Transformed = Source>(\n decoder: Decoder<StreamType, Source>,\n transform: (input: Source) => Transformed,\n controller: TransformStreamDefaultController<Transformed>,\n) => {\n try {\n const decoded = decoder.decode();\n if (!decoded) return;\n\n const transformed = transform(decoded);\n controller.enqueue(transformed);\n } catch (error) {\n controller.error(new Error(`Decoding error: ${error?.toString()}`));\n }\n};\n","import { v4 as randomUUID } from 'uuid';\nimport type {\n Event,\n ReadEvent,\n ReadEventMetadataWithGlobalPosition,\n} from '../typing';\nimport {\n type AggregateStreamOptions,\n type AggregateStreamResult,\n type AppendToStreamOptions,\n type AppendToStreamResult,\n type DefaultStreamVersionType,\n type EventStore,\n type ReadStreamOptions,\n type ReadStreamResult,\n} from './eventStore';\nimport { assertExpectedVersionMatchesCurrent } from './expectedVersion';\n\nexport type EventHandler<E extends Event = Event> = (\n eventEnvelope: ReadEvent<E>,\n) => void;\n\nexport const getInMemoryEventStore = (): EventStore<\n DefaultStreamVersionType,\n ReadEventMetadataWithGlobalPosition\n> => {\n const streams = new Map<string, ReadEvent[]>();\n\n const getAllEventsCount = () => {\n return Array.from<ReadEvent[]>(streams.values())\n .map((s) => s.length)\n .reduce((p, c) => p + c, 0);\n };\n\n return {\n async aggregateStream<State, EventType extends Event>(\n streamName: string,\n options: AggregateStreamOptions<State, EventType>,\n ): Promise<AggregateStreamResult<State> | null> {\n const { evolve, initialState, read } = options;\n\n const result = await this.readStream<EventType>(streamName, read);\n\n if (!result) return null;\n\n const events = result?.events ?? [];\n\n return {\n currentStreamVersion: BigInt(events.length),\n state: events.reduce(evolve, initialState()),\n };\n },\n\n readStream: <EventType extends Event>(\n streamName: string,\n options?: ReadStreamOptions,\n ): Promise<\n ReadStreamResult<\n EventType,\n DefaultStreamVersionType,\n ReadEventMetadataWithGlobalPosition\n >\n > => {\n const events = streams.get(streamName);\n const currentStreamVersion = events ? BigInt(events.length) : undefined;\n\n assertExpectedVersionMatchesCurrent(\n currentStreamVersion,\n options?.expectedStreamVersion,\n );\n\n const from = Number(options && 'from' in options ? options.from : 0);\n const to = Number(\n options && 'to' in options\n ? options.to\n : options && 'maxCount' in options && options.maxCount\n ? options.from + options.maxCount\n : events?.length ?? 1,\n );\n\n const resultEvents =\n events && events.length > 0\n ? events\n .map(\n (e) =>\n e as ReadEvent<\n EventType,\n ReadEventMetadataWithGlobalPosition\n >,\n )\n .slice(from, to)\n : [];\n\n const result: ReadStreamResult<\n EventType,\n DefaultStreamVersionType,\n ReadEventMetadataWithGlobalPosition\n > =\n events && events.length > 0\n ? {\n currentStreamVersion: currentStreamVersion!,\n events: resultEvents,\n }\n : null;\n\n return Promise.resolve(result);\n },\n\n appendToStream: <EventType extends Event>(\n streamName: string,\n events: EventType[],\n options?: AppendToStreamOptions,\n ): Promise<AppendToStreamResult> => {\n const currentEvents = streams.get(streamName) ?? [];\n const currentStreamVersion =\n currentEvents.length > 0 ? BigInt(currentEvents.length) : undefined;\n\n assertExpectedVersionMatchesCurrent(\n currentStreamVersion,\n options?.expectedStreamVersion,\n );\n\n const eventEnvelopes: ReadEvent<\n EventType,\n ReadEventMetadataWithGlobalPosition\n >[] = events.map((event, index) => {\n return {\n ...event,\n metadata: {\n ...(event.metadata ?? {}),\n streamName,\n eventId: randomUUID(),\n streamPosition: BigInt(currentEvents.length + index + 1),\n globalPosition: BigInt(getAllEventsCount() + index + 1),\n },\n };\n });\n\n const positionOfLastEventInTheStream = BigInt(\n eventEnvelopes.slice(-1)[0]!.metadata.streamPosition,\n );\n\n streams.set(streamName, [...currentEvents, ...eventEnvelopes]);\n\n const result: AppendToStreamResult = {\n nextExpectedStreamVersion: positionOfLastEventInTheStream,\n };\n\n return Promise.resolve(result);\n },\n };\n};\n"],"mappings":"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","names":["ParseError","text","JSONParser","value","options","_","v","parsed","deepEquals","left","right","isEquatable","val","index","keys1","keys2","key","AssertionError","message","assertFails","message","AssertionError","assertDeepEqual","actual","expected","message","deepEquals","AssertionError","JSONParser","assertTrue","condition","message","AssertionError","assertOk","obj","assertEqual","expected","actual","JSONParser","assertNotEqual","other","assertIsNotNull","result","assertThatArray","array","assertEqual","assertNotEqual","length","other","assertTrue","ts","o","deepEquals","i","elem","a","matches","item","ValidationErrors","isNumber","val","isString","isErrorConstructor","expect","EmmettError","_EmmettError","options","errorCode","isNumber","message","isString","ConcurrencyError","_ConcurrencyError","current","expected","event","type","data","metadata","projection","definition","STREAM_EXISTS","STREAM_DOES_NOT_EXIST","NO_CONCURRENCY_CHECK","ExpectedVersionConflictError","_ExpectedVersionConflictError","ConcurrencyError","current","expected","retry","TransformStream","randomUUID"]}
|
|
@@ -4,4 +4,4 @@ is not equal to
|
|
|
4
4
|
${l.stringify(e)}`)))};function o(e,t){if(!e)throw new i(_nullishCoalesce(t, () => ("Condition is false")))}function h(e,t){if(!e)throw new i(_nullishCoalesce(t, () => ("Condition is not truthy")))}function c(e,t,r){if(e!==t)throw new i(_nullishCoalesce(r, () => (`Objects are not equal:
|
|
5
5
|
Expected: ${l.stringify(e)}
|
|
6
6
|
Actual:${l.stringify(t)}`)))}function m(e,t,r){if(e===t)throw new i(_nullishCoalesce(r, () => (`Objects are equal: ${l.stringify(e)}`)))}function A(e){m(e,null),h(e)}var k=e=>({isEmpty:()=>c(e.length,0),isNotEmpty:()=>m(e.length,0),hasSize:t=>c(e.length,t),containsElements:(...t)=>{o(t.every(r=>t.some(a=>s(r,a))))},containsExactlyInAnyOrder:(...t)=>{c(e.length,t.length),o(e.every(r=>t.some(a=>s(r,a))))},containsExactlyInAnyOrderElementsOf:t=>{c(e.length,t.length),o(e.every(r=>t.some(a=>s(r,a))))},containsExactlyElementsOf:t=>{c(e.length,t.length);for(let r=0;r<e.length;r++)o(s(e[r],t[r]))},containsExactly:t=>{c(e.length,1),o(s(e[0],t))},contains:t=>{o(e.some(r=>s(r,t)))},containsOnlyOnceElementsOf:t=>{o(t.map(r=>e.filter(a=>s(a,r)).length).filter(r=>r===1).length===t.length)},containsAnyOf:(...t)=>{o(e.some(r=>t.some(a=>s(r,a))))},allMatch:t=>{o(e.every(t))},anyMatches:t=>{o(e.some(t))},allMatchAsync:async t=>{for(let r of e)o(await t(r))}});var g=(e=>(e.NOT_A_NONEMPTY_STRING="NOT_A_NONEMPTY_STRING",e.NOT_A_POSITIVE_NUMBER="NOT_A_POSITIVE_NUMBER",e.NOT_AN_UNSIGNED_BIGINT="NOT_AN_UNSIGNED_BIGINT",e))(g||{}),y=e=>typeof e=="number"&&e===e,w=e=>typeof e=="string";var E=e=>typeof e=="function"&&e.prototype&&e.prototype.constructor===e,d=class S extends Error{constructor(t){let r=t&&typeof t=="object"&&"errorCode"in t?t.errorCode:y(t)?t:500,a=t&&typeof t=="object"&&"message"in t?t.message:w(t)?t:`Error with status code '${r}' ocurred during Emmett processing`;super(a),this.errorCode=r,Object.setPrototypeOf(this,S.prototype)}},f=class b extends d{constructor(t,r,a){super({errorCode:412,message:_nullishCoalesce(a, () => (`Expected version ${r.toString()} does not match current ${_optionalChain([t, 'optionalAccess', _8 => _8.toString, 'call', _9 => _9()])}`))}),this.current=t,this.expected=r,Object.setPrototypeOf(this,b.prototype)}};var I=(e,t,r)=>({type:e,data:t,metadata:r});var M=e=>e;var j="STREAM_EXISTS",v= exports.m ="STREAM_DOES_NOT_EXIST",x= exports.n ="NO_CONCURRENCY_CHECK";var _=class N extends f{constructor(t,r){super(_optionalChain([t, 'optionalAccess', _10 => _10.toString, 'call', _11 => _11()]),_optionalChain([r, 'optionalAccess', _12 => _12.toString, 'call', _13 => _13()])),Object.setPrototypeOf(this,N.prototype)}};var _asyncretry = require('async-retry'); var _asyncretry2 = _interopRequireDefault(_asyncretry);var _webstreamspolyfill = require('web-streams-polyfill');var _uuid = require('uuid');exports.a = l; exports.b = i; exports.c = T; exports.d = C; exports.e = o; exports.f = c; exports.g = A; exports.h = k; exports.i = E; exports.j = I; exports.k = M; exports.l = j; exports.m = v; exports.n = x; exports.o = _;
|
|
7
|
-
//# sourceMappingURL=chunk-
|
|
7
|
+
//# sourceMappingURL=chunk-QB7BC56W.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../emmett/src/serialization/json/JSONParser.ts","../../emmett/src/utils/deepEquals.ts","../../emmett/src/testing/assertions.ts","../../emmett/src/validation/index.ts","../../emmett/src/errors/index.ts","../../emmett/src/typing/event.ts","../../emmett/src/projections/index.ts","../../emmett/src/eventStore/expectedVersion.ts","../../emmett/src/streaming/restream.ts","../../emmett/src/eventStore/inMemoryEventStore.ts"],"names":["ParseError","text","JSONParser","value","options","_","v","parsed","deepEquals","left","right","isEquatable","val","index","keys1","keys2","key","AssertionError","message","assertFails","assertDeepEqual","actual","expected","assertTrue","condition","assertOk","obj","assertEqual","assertNotEqual","other","assertIsNotNull","result","assertThatArray","array","length","ts","o","i","elem","a","matches","item","ValidationErrors","isNumber","isString","isErrorConstructor","expect","EmmettError","_EmmettError","errorCode","ConcurrencyError","_ConcurrencyError","current","event","type","data","metadata","projection","definition","STREAM_EXISTS","STREAM_DOES_NOT_EXIST","NO_CONCURRENCY_CHECK","ExpectedVersionConflictError","_ExpectedVersionConflictError","retry","TransformStream","randomUUID"],"mappings":"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","sourcesContent":["export class ParseError extends Error {\n constructor(text: string) {\n super(`Cannot parse! ${text}`);\n }\n}\n\nexport type Mapper<From, To = From> =\n | ((value: unknown) => To)\n | ((value: Partial<From>) => To)\n | ((value: From) => To)\n | ((value: Partial<To>) => To)\n | ((value: To) => To)\n | ((value: Partial<To | From>) => To)\n | ((value: To | From) => To);\n\nexport type MapperArgs<From, To = From> = Partial<From> &\n From &\n Partial<To> &\n To;\n\nexport type ParseOptions<From, To = From> = {\n reviver?: (key: string, value: unknown) => unknown;\n map?: Mapper<From, To>;\n typeCheck?: <To>(value: unknown) => value is To;\n};\n\nexport type StringifyOptions<From, To = From> = {\n map?: Mapper<From, To>;\n};\n\nexport const JSONParser = {\n stringify: <From, To = From>(\n value: From,\n options?: StringifyOptions<From, To>,\n ) => {\n return JSON.stringify(\n options?.map ? options.map(value as MapperArgs<From, To>) : value,\n //TODO: Consider adding support to DateTime and adding specific format to mark that's a bigint\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n (_, v) => (typeof v === 'bigint' ? v.toString() : v),\n );\n },\n parse: <From, To = From>(\n text: string,\n options?: ParseOptions<From, To>,\n ): To | undefined => {\n const parsed: unknown = JSON.parse(text, options?.reviver);\n\n if (options?.typeCheck && !options?.typeCheck<To>(parsed))\n throw new ParseError(text);\n\n return options?.map\n ? options.map(parsed as MapperArgs<From, To>)\n : (parsed as To | undefined);\n },\n};\n","export const deepEquals = <T>(left: T, right: T): boolean => {\n if (isEquatable(left)) {\n return left.equals(right);\n }\n\n if (Array.isArray(left)) {\n return (\n Array.isArray(right) &&\n left.length === right.length &&\n left.every((val, index) => deepEquals(val, right[index]))\n );\n }\n\n if (\n typeof left !== 'object' ||\n typeof right !== 'object' ||\n left === null ||\n right === null\n ) {\n return left === right;\n }\n\n if (Array.isArray(right)) return false;\n\n const keys1 = Object.keys(left);\n const keys2 = Object.keys(right);\n\n if (\n keys1.length !== keys2.length ||\n !keys1.every((key) => keys2.includes(key))\n )\n return false;\n\n for (const key in left) {\n if (left[key] instanceof Function && right[key] instanceof Function)\n continue;\n\n const isEqual = deepEquals(left[key], right[key]);\n if (!isEqual) {\n return false;\n }\n }\n\n return true;\n};\n\nexport type Equatable<T> = { equals: (right: T) => boolean } & T;\n\nexport const isEquatable = <T>(left: T): left is Equatable<T> => {\n return (\n left &&\n typeof left === 'object' &&\n 'equals' in left &&\n typeof left['equals'] === 'function'\n );\n};\n","import { JSONParser } from '../serialization';\nimport type { DefaultRecord } from '../typing';\nimport { deepEquals } from '../utils';\n\nexport class AssertionError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\nexport const isSubset = (superObj: unknown, subObj: unknown): boolean => {\n const sup = superObj as DefaultRecord;\n const sub = subObj as DefaultRecord;\n\n assertOk(sup);\n assertOk(sub);\n\n return Object.keys(sub).every((ele: string) => {\n if (typeof sub[ele] == 'object') {\n return isSubset(sup[ele], sub[ele]);\n }\n return sub[ele] === sup[ele];\n });\n};\n\nexport const assertFails = (message?: string) => {\n throw new AssertionError(message ?? 'That should not ever happened, right?');\n};\n\nexport const assertThrowsAsync = async <TError extends Error>(\n fun: () => Promise<void>,\n errorCheck?: (error: Error) => boolean,\n): Promise<TError> => {\n try {\n await fun();\n throw new AssertionError(\"Function didn't throw expected error\");\n } catch (error) {\n const typedError = error as TError;\n if (errorCheck) assertTrue(errorCheck(typedError));\n return typedError;\n }\n};\n\nexport const assertThrows = <TError extends Error>(\n fun: () => void,\n errorCheck?: (error: Error) => boolean,\n): TError => {\n try {\n fun();\n throw new AssertionError(\"Function didn't throw expected error\");\n } catch (error) {\n const typedError = error as TError;\n if (errorCheck) assertTrue(errorCheck(typedError));\n return typedError;\n }\n};\nexport const assertMatches = (\n actual: unknown,\n expected: unknown,\n message?: string,\n) => {\n if (!isSubset(actual, expected))\n throw new AssertionError(\n message ??\n `subObj:\\n${JSONParser.stringify(expected)}\\nis not subset of\\n${JSONParser.stringify(actual)}`,\n );\n};\n\nexport const assertDeepEqual = <T = unknown>(\n actual: T,\n expected: T,\n message?: string,\n) => {\n if (!deepEquals(actual, expected))\n throw new AssertionError(\n message ??\n `subObj:\\n${JSONParser.stringify(expected)}\\nis not equal to\\n${JSONParser.stringify(actual)}`,\n );\n};\n\nexport const assertNotDeepEqual = <T = unknown>(\n actual: T,\n expected: T,\n message?: string,\n) => {\n if (deepEquals(actual, expected))\n throw new AssertionError(\n message ??\n `subObj:\\n${JSONParser.stringify(expected)}\\nis equals to\\n${JSONParser.stringify(actual)}`,\n );\n};\n\nexport const assertThat = <T>(item: T) => {\n return {\n isEqualTo: (other: T) => assertTrue(deepEquals(item, other)),\n };\n};\n\nexport function assertFalse(\n condition: boolean,\n message?: string,\n): asserts condition is false {\n if (condition) throw new AssertionError(message ?? `Condition is false`);\n}\n\nexport function assertTrue(\n condition: boolean,\n message?: string,\n): asserts condition is true {\n if (!condition) throw new AssertionError(message ?? `Condition is false`);\n}\n\nexport function assertOk<T>(\n obj: T | null | undefined,\n message?: string,\n): asserts obj is T {\n if (!obj) throw new AssertionError(message ?? `Condition is not truthy`);\n}\n\nexport function assertEqual<T>(\n expected: T | null | undefined,\n actual: T | null | undefined,\n message?: string,\n): void {\n if (expected !== actual)\n throw new AssertionError(\n message ??\n `Objects are not equal:\\nExpected: ${JSONParser.stringify(expected)}\\nActual:${JSONParser.stringify(actual)}`,\n );\n}\n\nexport function assertNotEqual<T>(\n obj: T | null | undefined,\n other: T | null | undefined,\n message?: string,\n): void {\n if (obj === other)\n throw new AssertionError(\n message ?? `Objects are equal: ${JSONParser.stringify(obj)}`,\n );\n}\n\nexport function assertIsNotNull<T extends object | bigint>(\n result: T | null,\n): asserts result is T {\n assertNotEqual(result, null);\n assertOk(result);\n}\n\nexport function assertIsNull<T extends object>(\n result: T | null,\n): asserts result is null {\n assertEqual(result, null);\n}\n\ntype Call = {\n arguments: unknown[];\n result: unknown;\n target: unknown;\n this: unknown;\n};\n\nexport type ArgumentMatcher = (arg: unknown) => boolean;\n\nexport const argValue =\n <T>(value: T): ArgumentMatcher =>\n (arg) =>\n deepEquals(arg, value);\n\nexport const argMatches =\n <T>(matches: (arg: T) => boolean): ArgumentMatcher =>\n (arg) =>\n matches(arg as T);\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport type MockedFunction = Function & { mock?: { calls: Call[] } };\n\nexport function verifyThat(fn: MockedFunction) {\n return {\n calledTimes: (times: number) => {\n assertEqual(fn.mock?.calls?.length, times);\n },\n notCalled: () => {\n assertEqual(fn?.mock?.calls?.length, 0);\n },\n called: () => {\n assertTrue(\n fn.mock?.calls.length !== undefined && fn.mock.calls.length > 0,\n );\n },\n calledWith: (...args: unknown[]) => {\n assertTrue(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length >= 1 &&\n fn.mock.calls.some((call) => deepEquals(call.arguments, args)),\n );\n },\n calledOnceWith: (...args: unknown[]) => {\n assertTrue(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length === 1 &&\n fn.mock.calls.some((call) => deepEquals(call.arguments, args)),\n );\n },\n calledWithArgumentMatching: (...matches: ArgumentMatcher[]) => {\n assertTrue(\n fn.mock?.calls.length !== undefined && fn.mock.calls.length >= 1,\n );\n assertTrue(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length >= 1 &&\n fn.mock.calls.some(\n (call) =>\n call.arguments &&\n call.arguments.length >= matches.length &&\n matches.every((match, index) => match(call.arguments[index])),\n ),\n );\n },\n notCalledWithArgumentMatching: (...matches: ArgumentMatcher[]) => {\n assertFalse(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length >= 1 &&\n fn.mock.calls[0]!.arguments &&\n fn.mock.calls[0]!.arguments.length >= matches.length &&\n matches.every((match, index) =>\n match(fn.mock!.calls[0]!.arguments[index]),\n ),\n );\n },\n };\n}\n\nexport const assertThatArray = <T>(array: T[]) => {\n return {\n isEmpty: () => assertEqual(array.length, 0),\n isNotEmpty: () => assertNotEqual(array.length, 0),\n hasSize: (length: number) => assertEqual(array.length, length),\n containsElements: (...other: T[]) => {\n assertTrue(other.every((ts) => other.some((o) => deepEquals(ts, o))));\n },\n containsExactlyInAnyOrder: (...other: T[]) => {\n assertEqual(array.length, other.length);\n assertTrue(array.every((ts) => other.some((o) => deepEquals(ts, o))));\n },\n containsExactlyInAnyOrderElementsOf: (other: T[]) => {\n assertEqual(array.length, other.length);\n assertTrue(array.every((ts) => other.some((o) => deepEquals(ts, o))));\n },\n containsExactlyElementsOf: (other: T[]) => {\n assertEqual(array.length, other.length);\n for (let i = 0; i < array.length; i++) {\n assertTrue(deepEquals(array[i], other[i]));\n }\n },\n containsExactly: (elem: T) => {\n assertEqual(array.length, 1);\n assertTrue(deepEquals(array[0], elem));\n },\n contains: (elem: T) => {\n assertTrue(array.some((a) => deepEquals(a, elem)));\n },\n containsOnlyOnceElementsOf: (other: T[]) => {\n assertTrue(\n other\n .map((o) => array.filter((a) => deepEquals(a, o)).length)\n .filter((a) => a === 1).length === other.length,\n );\n },\n containsAnyOf: (...other: T[]) => {\n assertTrue(array.some((a) => other.some((o) => deepEquals(a, o))));\n },\n allMatch: (matches: (item: T) => boolean) => {\n assertTrue(array.every(matches));\n },\n anyMatches: (matches: (item: T) => boolean) => {\n assertTrue(array.some(matches));\n },\n allMatchAsync: async (\n matches: (item: T) => Promise<boolean>,\n ): Promise<void> => {\n for (const item of array) {\n assertTrue(await matches(item));\n }\n },\n };\n};\n","import { ValidationError } from '../errors';\n\nexport const enum ValidationErrors {\n NOT_A_NONEMPTY_STRING = 'NOT_A_NONEMPTY_STRING',\n NOT_A_POSITIVE_NUMBER = 'NOT_A_POSITIVE_NUMBER',\n NOT_AN_UNSIGNED_BIGINT = 'NOT_AN_UNSIGNED_BIGINT',\n}\n\nexport const isNumber = (val: unknown): val is number =>\n typeof val === 'number' && val === val;\n\nexport const isString = (val: unknown): val is string =>\n typeof val === 'string';\n\nexport const assertNotEmptyString = (value: unknown): string => {\n if (!isString(value) || value.length === 0) {\n throw new ValidationError(ValidationErrors.NOT_A_NONEMPTY_STRING);\n }\n return value;\n};\n\nexport const assertPositiveNumber = (value: unknown): number => {\n if (!isNumber(value) || value <= 0) {\n throw new ValidationError(ValidationErrors.NOT_A_POSITIVE_NUMBER);\n }\n return value;\n};\n\nexport const assertUnsignedBigInt = (value: string): bigint => {\n const number = BigInt(value);\n if (number < 0) {\n throw new ValidationError(ValidationErrors.NOT_AN_UNSIGNED_BIGINT);\n }\n return number;\n};\n\nexport * from './dates';\n","import { isNumber, isString } from '../validation';\n\nexport type ErrorConstructor<ErrorType extends Error> = new (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ...args: any[]\n) => ErrorType;\n\nexport const isErrorConstructor = <ErrorType extends Error>(\n // eslint-disable-next-line @typescript-eslint/ban-types\n expect: Function,\n): expect is ErrorConstructor<ErrorType> => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return (\n typeof expect === 'function' &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect.prototype &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect.prototype.constructor === expect\n );\n};\n\nexport class EmmettError extends Error {\n public errorCode: number;\n\n constructor(\n options?: { errorCode: number; message?: string } | string | number,\n ) {\n const errorCode =\n options && typeof options === 'object' && 'errorCode' in options\n ? options.errorCode\n : isNumber(options)\n ? options\n : 500;\n const message =\n options && typeof options === 'object' && 'message' in options\n ? options.message\n : isString(options)\n ? options\n : `Error with status code '${errorCode}' ocurred during Emmett processing`;\n\n super(message);\n this.errorCode = errorCode;\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, EmmettError.prototype);\n }\n}\n\nexport class ConcurrencyError extends EmmettError {\n constructor(\n public current: string | undefined,\n public expected: string,\n message?: string,\n ) {\n super({\n errorCode: 412,\n message:\n message ??\n `Expected version ${expected.toString()} does not match current ${current?.toString()}`,\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, ConcurrencyError.prototype);\n }\n}\n\nexport class ValidationError extends EmmettError {\n constructor(message?: string) {\n super({\n errorCode: 400,\n message: message ?? `Validation Error ocurred during Emmett processing`,\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\nexport class IllegalStateError extends EmmettError {\n constructor(message?: string) {\n super({\n errorCode: 403,\n message: message ?? `Illegal State ocurred during Emmett processing`,\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, IllegalStateError.prototype);\n }\n}\n\nexport class NotFoundError extends EmmettError {\n constructor(options?: { id: string; type: string; message?: string }) {\n super({\n errorCode: 404,\n message:\n options?.message ??\n (options?.id\n ? options.type\n ? `${options.type} with ${options.id} was not found during Emmett processing`\n : `State with ${options.id} was not found during Emmett processing`\n : options?.type\n ? `${options.type} was not found during Emmett processing`\n : 'State was not found during Emmett processing'),\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, NotFoundError.prototype);\n }\n}\n","import type { DefaultRecord, Flavour } from './';\n\nexport type Event<\n EventType extends string = string,\n EventData extends DefaultRecord = DefaultRecord,\n EventMetaData extends DefaultRecord = DefaultRecord,\n> = Flavour<\n Readonly<{\n type: EventType;\n data: EventData;\n metadata?: EventMetaData;\n }>,\n 'Event'\n>;\n\nexport type EventTypeOf<T extends Event> = T['type'];\nexport type EventDataOf<T extends Event> = T['data'];\nexport type EventMetaDataOf<T extends Event> = T['metadata'];\n\nexport type CanHandle<T extends Event> = EventTypeOf<T>[];\n\nexport type CreateEventType<\n EventType extends string,\n EventData extends DefaultRecord,\n EventMetaData extends DefaultRecord | undefined,\n> = Readonly<{\n type: EventType;\n data: EventData;\n metadata?: EventMetaData;\n}>;\n\nexport const event = <EventType extends Event>(\n type: EventTypeOf<EventType>,\n data: EventDataOf<EventType>,\n metadata?: EventMetaDataOf<EventType>,\n): CreateEventType<\n EventTypeOf<EventType>,\n EventDataOf<EventType>,\n EventMetaDataOf<EventType>\n> => {\n return {\n type,\n data,\n metadata,\n };\n};\n\nexport type ReadEvent<\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadata = EventMetaDataOf<EventType> & ReadEventMetadata,\n> = CreateEventType<\n EventTypeOf<EventType>,\n EventDataOf<EventType>,\n EventMetaDataType\n> &\n EventType & { metadata: EventMetaDataType };\n\nexport type ReadEventMetadata = Readonly<{\n eventId: string;\n streamPosition: bigint;\n streamName: string;\n}>;\n\nexport type ReadEventMetadataWithGlobalPosition = ReadEventMetadata & {\n globalPosition: bigint;\n};\n","import type { CanHandle, DefaultRecord, Event, ReadEvent } from '../typing';\n\nexport type ProjectionHandlingType = 'inline' | 'async';\n\nexport type ProjectionHandler<\n EventType extends Event = Event,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> = (\n events: ReadEvent<EventType>[],\n context: ProjectionHandlerContext,\n) => Promise<void> | void;\n\nexport interface ProjectionDefinition<\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> {\n name?: string;\n canHandle: CanHandle<Event>;\n handle: ProjectionHandler<Event, ProjectionHandlerContext>;\n}\n\nexport interface TypedProjectionDefinition<\n EventType extends Event = Event,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> {\n name?: string;\n canHandle: CanHandle<EventType>;\n handle: ProjectionHandler<EventType, ProjectionHandlerContext>;\n}\n\nexport type ProjectionRegistration<\n HandlingType extends ProjectionHandlingType,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> = {\n type: HandlingType;\n projection: ProjectionDefinition<ProjectionHandlerContext>;\n};\n\nexport const projection = <\n EventType extends Event = Event,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n ProjectionDefintionType extends TypedProjectionDefinition<\n EventType,\n ProjectionHandlerContext\n > = ProjectionDefinition<ProjectionHandlerContext>,\n>(\n definition: ProjectionDefintionType,\n): ProjectionDefintionType => definition;\n\nexport const inlineProjections = <\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n ProjectionDefintionType extends\n ProjectionDefinition<ProjectionHandlerContext> = ProjectionDefinition<ProjectionHandlerContext>,\n>(\n definitions: ProjectionDefintionType[],\n): ProjectionRegistration<'inline', ProjectionHandlerContext>[] =>\n definitions.map((projection) => ({ type: 'inline', projection }));\n\nexport const asyncProjections = <\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n ProjectionDefintionType extends\n ProjectionDefinition<ProjectionHandlerContext> = ProjectionDefinition<ProjectionHandlerContext>,\n>(\n definitions: ProjectionDefintionType[],\n): ProjectionRegistration<'async', ProjectionHandlerContext>[] =>\n definitions.map((projection) => ({ type: 'async', projection }));\n\nexport const projections = {\n inline: inlineProjections,\n async: asyncProjections,\n};\n","import { ConcurrencyError } from '../errors';\nimport type { Flavour } from '../typing';\nimport type { DefaultStreamVersionType } from './eventStore';\n\nexport type ExpectedStreamVersion<VersionType = DefaultStreamVersionType> =\n | ExpectedStreamVersionWithValue<VersionType>\n | ExpectedStreamVersionGeneral;\n\nexport type ExpectedStreamVersionWithValue<\n VersionType = DefaultStreamVersionType,\n> = Flavour<VersionType, 'StreamVersion'>;\n\nexport type ExpectedStreamVersionGeneral = Flavour<\n 'STREAM_EXISTS' | 'STREAM_DOES_NOT_EXIST' | 'NO_CONCURRENCY_CHECK',\n 'StreamVersion'\n>;\n\nexport const STREAM_EXISTS = 'STREAM_EXISTS' as ExpectedStreamVersionGeneral;\nexport const STREAM_DOES_NOT_EXIST =\n 'STREAM_DOES_NOT_EXIST' as ExpectedStreamVersionGeneral;\nexport const NO_CONCURRENCY_CHECK =\n 'NO_CONCURRENCY_CHECK' as ExpectedStreamVersionGeneral;\n\nexport const matchesExpectedVersion = <\n StreamVersion = DefaultStreamVersionType,\n>(\n current: StreamVersion | undefined,\n expected: ExpectedStreamVersion<StreamVersion>,\n): boolean => {\n if (expected === NO_CONCURRENCY_CHECK) return true;\n\n if (expected == STREAM_DOES_NOT_EXIST) return current === undefined;\n\n if (expected == STREAM_EXISTS) return current !== undefined;\n\n return current === expected;\n};\n\nexport const assertExpectedVersionMatchesCurrent = <\n StreamVersion = DefaultStreamVersionType,\n>(\n current: StreamVersion | undefined,\n expected: ExpectedStreamVersion<StreamVersion> | undefined,\n): void => {\n expected ??= NO_CONCURRENCY_CHECK;\n\n if (!matchesExpectedVersion(current, expected))\n throw new ExpectedVersionConflictError(current, expected);\n};\n\nexport class ExpectedVersionConflictError<\n VersionType = DefaultStreamVersionType,\n> extends ConcurrencyError {\n constructor(\n current: VersionType | undefined,\n expected: ExpectedStreamVersion<VersionType>,\n ) {\n super(current?.toString(), expected?.toString());\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, ExpectedVersionConflictError.prototype);\n }\n}\n","import retry from 'async-retry';\nimport {\n ReadableStream,\n ReadableStreamDefaultReader,\n TransformStream,\n TransformStreamDefaultController,\n} from 'web-streams-polyfill';\nimport type { Decoder } from './decoders';\nimport { DefaultDecoder } from './decoders/composite';\n\nexport const restream = <\n Source = unknown,\n Transformed = Source,\n StreamType = object,\n>(\n createSourceStream: () => ReadableStream<StreamType>,\n transform: (input: Source) => Transformed = (source) =>\n source as unknown as Transformed,\n retryOptions: retry.Options = { forever: true, minTimeout: 25 },\n decoder: Decoder<StreamType, Source> = new DefaultDecoder<Source>(),\n): ReadableStream<Transformed> =>\n new TransformStream<Source, Transformed>({\n start(controller) {\n retry(\n () => onRestream(createSourceStream, controller, transform, decoder),\n retryOptions,\n ).catch((error) => {\n controller.error(error);\n });\n },\n }).readable;\n\nconst onRestream = async <StreamType, Source, Transformed = Source>(\n createSourceStream: () => ReadableStream<StreamType>,\n controller: TransformStreamDefaultController<Transformed>,\n transform: (input: Source) => Transformed,\n decoder: Decoder<StreamType, Source>,\n): Promise<void> => {\n const sourceStream = createSourceStream();\n const reader = sourceStream.getReader();\n try {\n let done: boolean;\n\n do {\n done = await restreamChunk(reader, controller, transform, decoder);\n } while (!done);\n } finally {\n reader.releaseLock();\n }\n};\n\nconst restreamChunk = async <StreamType, Source, Transformed = Source>(\n reader: ReadableStreamDefaultReader<StreamType>,\n controller: TransformStreamDefaultController<Transformed>,\n transform: (input: Source) => Transformed,\n decoder: Decoder<StreamType, Source>,\n): Promise<boolean> => {\n const { done: isDone, value } = await reader.read();\n\n if (value) decoder.addToBuffer(value);\n\n if (!isDone && !decoder.hasCompleteMessage()) return false;\n\n decodeAndTransform(decoder, transform, controller);\n\n if (isDone) {\n controller.terminate();\n }\n\n return isDone;\n};\n\nconst decodeAndTransform = <StreamType, Source, Transformed = Source>(\n decoder: Decoder<StreamType, Source>,\n transform: (input: Source) => Transformed,\n controller: TransformStreamDefaultController<Transformed>,\n) => {\n try {\n const decoded = decoder.decode();\n if (!decoded) return;\n\n const transformed = transform(decoded);\n controller.enqueue(transformed);\n } catch (error) {\n controller.error(new Error(`Decoding error: ${error?.toString()}`));\n }\n};\n","import { v4 as randomUUID } from 'uuid';\nimport type {\n Event,\n ReadEvent,\n ReadEventMetadataWithGlobalPosition,\n} from '../typing';\nimport {\n type AggregateStreamOptions,\n type AggregateStreamResult,\n type AppendToStreamOptions,\n type AppendToStreamResult,\n type DefaultStreamVersionType,\n type EventStore,\n type ReadStreamOptions,\n type ReadStreamResult,\n} from './eventStore';\nimport { assertExpectedVersionMatchesCurrent } from './expectedVersion';\n\nexport type EventHandler<E extends Event = Event> = (\n eventEnvelope: ReadEvent<E>,\n) => void;\n\nexport const getInMemoryEventStore = (): EventStore<\n DefaultStreamVersionType,\n ReadEventMetadataWithGlobalPosition\n> => {\n const streams = new Map<string, ReadEvent[]>();\n\n const getAllEventsCount = () => {\n return Array.from<ReadEvent[]>(streams.values())\n .map((s) => s.length)\n .reduce((p, c) => p + c, 0);\n };\n\n return {\n async aggregateStream<State, EventType extends Event>(\n streamName: string,\n options: AggregateStreamOptions<State, EventType>,\n ): Promise<AggregateStreamResult<State> | null> {\n const { evolve, initialState, read } = options;\n\n const result = await this.readStream<EventType>(streamName, read);\n\n if (!result) return null;\n\n const events = result?.events ?? [];\n\n return {\n currentStreamVersion: BigInt(events.length),\n state: events.reduce(evolve, initialState()),\n };\n },\n\n readStream: <EventType extends Event>(\n streamName: string,\n options?: ReadStreamOptions,\n ): Promise<\n ReadStreamResult<\n EventType,\n DefaultStreamVersionType,\n ReadEventMetadataWithGlobalPosition\n >\n > => {\n const events = streams.get(streamName);\n const currentStreamVersion = events ? BigInt(events.length) : undefined;\n\n assertExpectedVersionMatchesCurrent(\n currentStreamVersion,\n options?.expectedStreamVersion,\n );\n\n const from = Number(options && 'from' in options ? options.from : 0);\n const to = Number(\n options && 'to' in options\n ? options.to\n : options && 'maxCount' in options && options.maxCount\n ? options.from + options.maxCount\n : events?.length ?? 1,\n );\n\n const resultEvents =\n events && events.length > 0\n ? events\n .map(\n (e) =>\n e as ReadEvent<\n EventType,\n ReadEventMetadataWithGlobalPosition\n >,\n )\n .slice(from, to)\n : [];\n\n const result: ReadStreamResult<\n EventType,\n DefaultStreamVersionType,\n ReadEventMetadataWithGlobalPosition\n > =\n events && events.length > 0\n ? {\n currentStreamVersion: currentStreamVersion!,\n events: resultEvents,\n }\n : null;\n\n return Promise.resolve(result);\n },\n\n appendToStream: <EventType extends Event>(\n streamName: string,\n events: EventType[],\n options?: AppendToStreamOptions,\n ): Promise<AppendToStreamResult> => {\n const currentEvents = streams.get(streamName) ?? [];\n const currentStreamVersion =\n currentEvents.length > 0 ? BigInt(currentEvents.length) : undefined;\n\n assertExpectedVersionMatchesCurrent(\n currentStreamVersion,\n options?.expectedStreamVersion,\n );\n\n const eventEnvelopes: ReadEvent<\n EventType,\n ReadEventMetadataWithGlobalPosition\n >[] = events.map((event, index) => {\n return {\n ...event,\n metadata: {\n ...(event.metadata ?? {}),\n streamName,\n eventId: randomUUID(),\n streamPosition: BigInt(currentEvents.length + index + 1),\n globalPosition: BigInt(getAllEventsCount() + index + 1),\n },\n };\n });\n\n const positionOfLastEventInTheStream = BigInt(\n eventEnvelopes.slice(-1)[0]!.metadata.streamPosition,\n );\n\n streams.set(streamName, [...currentEvents, ...eventEnvelopes]);\n\n const result: AppendToStreamResult = {\n nextExpectedStreamVersion: positionOfLastEventInTheStream,\n };\n\n return Promise.resolve(result);\n },\n };\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../emmett/src/serialization/json/JSONParser.ts","../../emmett/src/utils/deepEquals.ts","../../emmett/src/testing/assertions.ts","../../emmett/src/validation/index.ts","../../emmett/src/errors/index.ts","../../emmett/src/typing/event.ts","../../emmett/src/projections/index.ts","../../emmett/src/eventStore/expectedVersion.ts","../../emmett/src/streaming/restream.ts","../../emmett/src/eventStore/inMemoryEventStore.ts"],"names":["ParseError","text","JSONParser","value","options","_","v","parsed","deepEquals","left","right","isEquatable","val","index","keys1","keys2","key","AssertionError","message","assertFails","assertDeepEqual","actual","expected","assertTrue","condition","assertOk","obj","assertEqual","assertNotEqual","other","assertIsNotNull","result","assertThatArray","array","length","ts","o","i","elem","a","matches","item","ValidationErrors","isNumber","isString","isErrorConstructor","expect","EmmettError","_EmmettError","errorCode","ConcurrencyError","_ConcurrencyError","current","event","type","data","metadata","projection","definition","STREAM_EXISTS","STREAM_DOES_NOT_EXIST","NO_CONCURRENCY_CHECK","ExpectedVersionConflictError","_ExpectedVersionConflictError","retry","TransformStream","randomUUID"],"mappings":"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","sourcesContent":["export class ParseError extends Error {\n constructor(text: string) {\n super(`Cannot parse! ${text}`);\n }\n}\n\nexport type Mapper<From, To = From> =\n | ((value: unknown) => To)\n | ((value: Partial<From>) => To)\n | ((value: From) => To)\n | ((value: Partial<To>) => To)\n | ((value: To) => To)\n | ((value: Partial<To | From>) => To)\n | ((value: To | From) => To);\n\nexport type MapperArgs<From, To = From> = Partial<From> &\n From &\n Partial<To> &\n To;\n\nexport type ParseOptions<From, To = From> = {\n reviver?: (key: string, value: unknown) => unknown;\n map?: Mapper<From, To>;\n typeCheck?: <To>(value: unknown) => value is To;\n};\n\nexport type StringifyOptions<From, To = From> = {\n map?: Mapper<From, To>;\n};\n\nexport const JSONParser = {\n stringify: <From, To = From>(\n value: From,\n options?: StringifyOptions<From, To>,\n ) => {\n return JSON.stringify(\n options?.map ? options.map(value as MapperArgs<From, To>) : value,\n //TODO: Consider adding support to DateTime and adding specific format to mark that's a bigint\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n (_, v) => (typeof v === 'bigint' ? v.toString() : v),\n );\n },\n parse: <From, To = From>(\n text: string,\n options?: ParseOptions<From, To>,\n ): To | undefined => {\n const parsed: unknown = JSON.parse(text, options?.reviver);\n\n if (options?.typeCheck && !options?.typeCheck<To>(parsed))\n throw new ParseError(text);\n\n return options?.map\n ? options.map(parsed as MapperArgs<From, To>)\n : (parsed as To | undefined);\n },\n};\n","export const deepEquals = <T>(left: T, right: T): boolean => {\n if (isEquatable(left)) {\n return left.equals(right);\n }\n\n if (Array.isArray(left)) {\n return (\n Array.isArray(right) &&\n left.length === right.length &&\n left.every((val, index) => deepEquals(val, right[index]))\n );\n }\n\n if (\n typeof left !== 'object' ||\n typeof right !== 'object' ||\n left === null ||\n right === null\n ) {\n return left === right;\n }\n\n if (Array.isArray(right)) return false;\n\n const keys1 = Object.keys(left);\n const keys2 = Object.keys(right);\n\n if (\n keys1.length !== keys2.length ||\n !keys1.every((key) => keys2.includes(key))\n )\n return false;\n\n for (const key in left) {\n if (left[key] instanceof Function && right[key] instanceof Function)\n continue;\n\n const isEqual = deepEquals(left[key], right[key]);\n if (!isEqual) {\n return false;\n }\n }\n\n return true;\n};\n\nexport type Equatable<T> = { equals: (right: T) => boolean } & T;\n\nexport const isEquatable = <T>(left: T): left is Equatable<T> => {\n return (\n left &&\n typeof left === 'object' &&\n 'equals' in left &&\n typeof left['equals'] === 'function'\n );\n};\n","import { JSONParser } from '../serialization';\nimport type { DefaultRecord } from '../typing';\nimport { deepEquals } from '../utils';\n\nexport class AssertionError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\nexport const isSubset = (superObj: unknown, subObj: unknown): boolean => {\n const sup = superObj as DefaultRecord;\n const sub = subObj as DefaultRecord;\n\n assertOk(sup);\n assertOk(sub);\n\n return Object.keys(sub).every((ele: string) => {\n if (typeof sub[ele] == 'object') {\n return isSubset(sup[ele], sub[ele]);\n }\n return sub[ele] === sup[ele];\n });\n};\n\nexport const assertFails = (message?: string) => {\n throw new AssertionError(message ?? 'That should not ever happened, right?');\n};\n\nexport const assertThrowsAsync = async <TError extends Error>(\n fun: () => Promise<void>,\n errorCheck?: (error: Error) => boolean,\n): Promise<TError> => {\n try {\n await fun();\n throw new AssertionError(\"Function didn't throw expected error\");\n } catch (error) {\n const typedError = error as TError;\n if (errorCheck) assertTrue(errorCheck(typedError));\n return typedError;\n }\n};\n\nexport const assertThrows = <TError extends Error>(\n fun: () => void,\n errorCheck?: (error: Error) => boolean,\n): TError => {\n try {\n fun();\n throw new AssertionError(\"Function didn't throw expected error\");\n } catch (error) {\n const typedError = error as TError;\n if (errorCheck) assertTrue(errorCheck(typedError));\n return typedError;\n }\n};\nexport const assertMatches = (\n actual: unknown,\n expected: unknown,\n message?: string,\n) => {\n if (!isSubset(actual, expected))\n throw new AssertionError(\n message ??\n `subObj:\\n${JSONParser.stringify(expected)}\\nis not subset of\\n${JSONParser.stringify(actual)}`,\n );\n};\n\nexport const assertDeepEqual = <T = unknown>(\n actual: T,\n expected: T,\n message?: string,\n) => {\n if (!deepEquals(actual, expected))\n throw new AssertionError(\n message ??\n `subObj:\\n${JSONParser.stringify(expected)}\\nis not equal to\\n${JSONParser.stringify(actual)}`,\n );\n};\n\nexport const assertNotDeepEqual = <T = unknown>(\n actual: T,\n expected: T,\n message?: string,\n) => {\n if (deepEquals(actual, expected))\n throw new AssertionError(\n message ??\n `subObj:\\n${JSONParser.stringify(expected)}\\nis equals to\\n${JSONParser.stringify(actual)}`,\n );\n};\n\nexport const assertThat = <T>(item: T) => {\n return {\n isEqualTo: (other: T) => assertTrue(deepEquals(item, other)),\n };\n};\n\nexport function assertFalse(\n condition: boolean,\n message?: string,\n): asserts condition is false {\n if (condition) throw new AssertionError(message ?? `Condition is false`);\n}\n\nexport function assertTrue(\n condition: boolean,\n message?: string,\n): asserts condition is true {\n if (!condition) throw new AssertionError(message ?? `Condition is false`);\n}\n\nexport function assertOk<T>(\n obj: T | null | undefined,\n message?: string,\n): asserts obj is T {\n if (!obj) throw new AssertionError(message ?? `Condition is not truthy`);\n}\n\nexport function assertEqual<T>(\n expected: T | null | undefined,\n actual: T | null | undefined,\n message?: string,\n): void {\n if (expected !== actual)\n throw new AssertionError(\n message ??\n `Objects are not equal:\\nExpected: ${JSONParser.stringify(expected)}\\nActual:${JSONParser.stringify(actual)}`,\n );\n}\n\nexport function assertNotEqual<T>(\n obj: T | null | undefined,\n other: T | null | undefined,\n message?: string,\n): void {\n if (obj === other)\n throw new AssertionError(\n message ?? `Objects are equal: ${JSONParser.stringify(obj)}`,\n );\n}\n\nexport function assertIsNotNull<T extends object | bigint>(\n result: T | null,\n): asserts result is T {\n assertNotEqual(result, null);\n assertOk(result);\n}\n\nexport function assertIsNull<T extends object>(\n result: T | null,\n): asserts result is null {\n assertEqual(result, null);\n}\n\ntype Call = {\n arguments: unknown[];\n result: unknown;\n target: unknown;\n this: unknown;\n};\n\nexport type ArgumentMatcher = (arg: unknown) => boolean;\n\nexport const argValue =\n <T>(value: T): ArgumentMatcher =>\n (arg) =>\n deepEquals(arg, value);\n\nexport const argMatches =\n <T>(matches: (arg: T) => boolean): ArgumentMatcher =>\n (arg) =>\n matches(arg as T);\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport type MockedFunction = Function & { mock?: { calls: Call[] } };\n\nexport function verifyThat(fn: MockedFunction) {\n return {\n calledTimes: (times: number) => {\n assertEqual(fn.mock?.calls?.length, times);\n },\n notCalled: () => {\n assertEqual(fn?.mock?.calls?.length, 0);\n },\n called: () => {\n assertTrue(\n fn.mock?.calls.length !== undefined && fn.mock.calls.length > 0,\n );\n },\n calledWith: (...args: unknown[]) => {\n assertTrue(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length >= 1 &&\n fn.mock.calls.some((call) => deepEquals(call.arguments, args)),\n );\n },\n calledOnceWith: (...args: unknown[]) => {\n assertTrue(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length === 1 &&\n fn.mock.calls.some((call) => deepEquals(call.arguments, args)),\n );\n },\n calledWithArgumentMatching: (...matches: ArgumentMatcher[]) => {\n assertTrue(\n fn.mock?.calls.length !== undefined && fn.mock.calls.length >= 1,\n );\n assertTrue(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length >= 1 &&\n fn.mock.calls.some(\n (call) =>\n call.arguments &&\n call.arguments.length >= matches.length &&\n matches.every((match, index) => match(call.arguments[index])),\n ),\n );\n },\n notCalledWithArgumentMatching: (...matches: ArgumentMatcher[]) => {\n assertFalse(\n fn.mock?.calls.length !== undefined &&\n fn.mock.calls.length >= 1 &&\n fn.mock.calls[0]!.arguments &&\n fn.mock.calls[0]!.arguments.length >= matches.length &&\n matches.every((match, index) =>\n match(fn.mock!.calls[0]!.arguments[index]),\n ),\n );\n },\n };\n}\n\nexport const assertThatArray = <T>(array: T[]) => {\n return {\n isEmpty: () => assertEqual(array.length, 0),\n isNotEmpty: () => assertNotEqual(array.length, 0),\n hasSize: (length: number) => assertEqual(array.length, length),\n containsElements: (...other: T[]) => {\n assertTrue(other.every((ts) => other.some((o) => deepEquals(ts, o))));\n },\n containsExactlyInAnyOrder: (...other: T[]) => {\n assertEqual(array.length, other.length);\n assertTrue(array.every((ts) => other.some((o) => deepEquals(ts, o))));\n },\n containsExactlyInAnyOrderElementsOf: (other: T[]) => {\n assertEqual(array.length, other.length);\n assertTrue(array.every((ts) => other.some((o) => deepEquals(ts, o))));\n },\n containsExactlyElementsOf: (other: T[]) => {\n assertEqual(array.length, other.length);\n for (let i = 0; i < array.length; i++) {\n assertTrue(deepEquals(array[i], other[i]));\n }\n },\n containsExactly: (elem: T) => {\n assertEqual(array.length, 1);\n assertTrue(deepEquals(array[0], elem));\n },\n contains: (elem: T) => {\n assertTrue(array.some((a) => deepEquals(a, elem)));\n },\n containsOnlyOnceElementsOf: (other: T[]) => {\n assertTrue(\n other\n .map((o) => array.filter((a) => deepEquals(a, o)).length)\n .filter((a) => a === 1).length === other.length,\n );\n },\n containsAnyOf: (...other: T[]) => {\n assertTrue(array.some((a) => other.some((o) => deepEquals(a, o))));\n },\n allMatch: (matches: (item: T) => boolean) => {\n assertTrue(array.every(matches));\n },\n anyMatches: (matches: (item: T) => boolean) => {\n assertTrue(array.some(matches));\n },\n allMatchAsync: async (\n matches: (item: T) => Promise<boolean>,\n ): Promise<void> => {\n for (const item of array) {\n assertTrue(await matches(item));\n }\n },\n };\n};\n","import { ValidationError } from '../errors';\n\nexport const enum ValidationErrors {\n NOT_A_NONEMPTY_STRING = 'NOT_A_NONEMPTY_STRING',\n NOT_A_POSITIVE_NUMBER = 'NOT_A_POSITIVE_NUMBER',\n NOT_AN_UNSIGNED_BIGINT = 'NOT_AN_UNSIGNED_BIGINT',\n}\n\nexport const isNumber = (val: unknown): val is number =>\n typeof val === 'number' && val === val;\n\nexport const isString = (val: unknown): val is string =>\n typeof val === 'string';\n\nexport const assertNotEmptyString = (value: unknown): string => {\n if (!isString(value) || value.length === 0) {\n throw new ValidationError(ValidationErrors.NOT_A_NONEMPTY_STRING);\n }\n return value;\n};\n\nexport const assertPositiveNumber = (value: unknown): number => {\n if (!isNumber(value) || value <= 0) {\n throw new ValidationError(ValidationErrors.NOT_A_POSITIVE_NUMBER);\n }\n return value;\n};\n\nexport const assertUnsignedBigInt = (value: string): bigint => {\n const number = BigInt(value);\n if (number < 0) {\n throw new ValidationError(ValidationErrors.NOT_AN_UNSIGNED_BIGINT);\n }\n return number;\n};\n\nexport * from './dates';\n","import { isNumber, isString } from '../validation';\n\nexport type ErrorConstructor<ErrorType extends Error> = new (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ...args: any[]\n) => ErrorType;\n\nexport const isErrorConstructor = <ErrorType extends Error>(\n // eslint-disable-next-line @typescript-eslint/ban-types\n expect: Function,\n): expect is ErrorConstructor<ErrorType> => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return (\n typeof expect === 'function' &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect.prototype &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect.prototype.constructor === expect\n );\n};\n\nexport class EmmettError extends Error {\n public errorCode: number;\n\n constructor(\n options?: { errorCode: number; message?: string } | string | number,\n ) {\n const errorCode =\n options && typeof options === 'object' && 'errorCode' in options\n ? options.errorCode\n : isNumber(options)\n ? options\n : 500;\n const message =\n options && typeof options === 'object' && 'message' in options\n ? options.message\n : isString(options)\n ? options\n : `Error with status code '${errorCode}' ocurred during Emmett processing`;\n\n super(message);\n this.errorCode = errorCode;\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, EmmettError.prototype);\n }\n}\n\nexport class ConcurrencyError extends EmmettError {\n constructor(\n public current: string | undefined,\n public expected: string,\n message?: string,\n ) {\n super({\n errorCode: 412,\n message:\n message ??\n `Expected version ${expected.toString()} does not match current ${current?.toString()}`,\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, ConcurrencyError.prototype);\n }\n}\n\nexport class ValidationError extends EmmettError {\n constructor(message?: string) {\n super({\n errorCode: 400,\n message: message ?? `Validation Error ocurred during Emmett processing`,\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\nexport class IllegalStateError extends EmmettError {\n constructor(message?: string) {\n super({\n errorCode: 403,\n message: message ?? `Illegal State ocurred during Emmett processing`,\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, IllegalStateError.prototype);\n }\n}\n\nexport class NotFoundError extends EmmettError {\n constructor(options?: { id: string; type: string; message?: string }) {\n super({\n errorCode: 404,\n message:\n options?.message ??\n (options?.id\n ? options.type\n ? `${options.type} with ${options.id} was not found during Emmett processing`\n : `State with ${options.id} was not found during Emmett processing`\n : options?.type\n ? `${options.type} was not found during Emmett processing`\n : 'State was not found during Emmett processing'),\n });\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, NotFoundError.prototype);\n }\n}\n","import type { DefaultRecord, Flavour } from './';\n\nexport type Event<\n EventType extends string = string,\n EventData extends DefaultRecord = DefaultRecord,\n EventMetaData extends DefaultRecord = DefaultRecord,\n> = Flavour<\n Readonly<{\n type: EventType;\n data: EventData;\n metadata?: EventMetaData;\n }>,\n 'Event'\n>;\n\nexport type EventTypeOf<T extends Event> = T['type'];\nexport type EventDataOf<T extends Event> = T['data'];\nexport type EventMetaDataOf<T extends Event> = T['metadata'];\n\nexport type CanHandle<T extends Event> = EventTypeOf<T>[];\n\nexport type CreateEventType<\n EventType extends string,\n EventData extends DefaultRecord,\n EventMetaData extends DefaultRecord | undefined,\n> = Readonly<{\n type: EventType;\n data: EventData;\n metadata?: EventMetaData;\n}>;\n\nexport const event = <EventType extends Event>(\n type: EventTypeOf<EventType>,\n data: EventDataOf<EventType>,\n metadata?: EventMetaDataOf<EventType>,\n): CreateEventType<\n EventTypeOf<EventType>,\n EventDataOf<EventType>,\n EventMetaDataOf<EventType>\n> => {\n return {\n type,\n data,\n metadata,\n };\n};\n\nexport type ReadEvent<\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadata = EventMetaDataOf<EventType> & ReadEventMetadata,\n> = CreateEventType<\n EventTypeOf<EventType>,\n EventDataOf<EventType>,\n EventMetaDataType\n> &\n EventType & { metadata: EventMetaDataType };\n\nexport type ReadEventMetadata = Readonly<{\n eventId: string;\n streamPosition: bigint;\n streamName: string;\n}>;\n\nexport type ReadEventMetadataWithGlobalPosition = ReadEventMetadata & {\n globalPosition: bigint;\n};\n","import type {\n CanHandle,\n DefaultRecord,\n Event,\n EventMetaDataOf,\n ReadEvent,\n ReadEventMetadata,\n} from '../typing';\n\nexport type ProjectionHandlingType = 'inline' | 'async';\n\nexport type ProjectionHandler<\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadata = EventMetaDataOf<EventType> & ReadEventMetadata,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> = (\n events: ReadEvent<EventType, EventMetaDataType>[],\n context: ProjectionHandlerContext,\n) => Promise<void> | void;\n\nexport interface ProjectionDefinition<\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> {\n name?: string;\n canHandle: CanHandle<Event>;\n handle: ProjectionHandler<Event, ReadEventMetadata, ProjectionHandlerContext>;\n}\n\nexport interface TypedProjectionDefinition<\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadata = EventMetaDataOf<EventType> & ReadEventMetadata,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> {\n name?: string;\n canHandle: CanHandle<EventType>;\n handle: ProjectionHandler<\n EventType,\n EventMetaDataType,\n ProjectionHandlerContext\n >;\n}\n\nexport type ProjectionRegistration<\n HandlingType extends ProjectionHandlingType,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n> = {\n type: HandlingType;\n projection: ProjectionDefinition<ProjectionHandlerContext>;\n};\n\nexport const projection = <\n EventType extends Event = Event,\n EventMetaDataType extends EventMetaDataOf<EventType> &\n ReadEventMetadata = EventMetaDataOf<EventType> & ReadEventMetadata,\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n ProjectionDefintionType extends TypedProjectionDefinition<\n EventType,\n EventMetaDataType,\n ProjectionHandlerContext\n > = ProjectionDefinition<ProjectionHandlerContext>,\n>(\n definition: ProjectionDefintionType,\n): ProjectionDefintionType => definition;\n\nexport const inlineProjections = <\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n ProjectionDefintionType extends\n ProjectionDefinition<ProjectionHandlerContext> = ProjectionDefinition<ProjectionHandlerContext>,\n>(\n definitions: ProjectionDefintionType[],\n): ProjectionRegistration<'inline', ProjectionHandlerContext>[] =>\n definitions.map((projection) => ({ type: 'inline', projection }));\n\nexport const asyncProjections = <\n ProjectionHandlerContext extends DefaultRecord = DefaultRecord,\n ProjectionDefintionType extends\n ProjectionDefinition<ProjectionHandlerContext> = ProjectionDefinition<ProjectionHandlerContext>,\n>(\n definitions: ProjectionDefintionType[],\n): ProjectionRegistration<'async', ProjectionHandlerContext>[] =>\n definitions.map((projection) => ({ type: 'async', projection }));\n\nexport const projections = {\n inline: inlineProjections,\n async: asyncProjections,\n};\n","import { ConcurrencyError } from '../errors';\nimport type { Flavour } from '../typing';\nimport type { DefaultStreamVersionType } from './eventStore';\n\nexport type ExpectedStreamVersion<VersionType = DefaultStreamVersionType> =\n | ExpectedStreamVersionWithValue<VersionType>\n | ExpectedStreamVersionGeneral;\n\nexport type ExpectedStreamVersionWithValue<\n VersionType = DefaultStreamVersionType,\n> = Flavour<VersionType, 'StreamVersion'>;\n\nexport type ExpectedStreamVersionGeneral = Flavour<\n 'STREAM_EXISTS' | 'STREAM_DOES_NOT_EXIST' | 'NO_CONCURRENCY_CHECK',\n 'StreamVersion'\n>;\n\nexport const STREAM_EXISTS = 'STREAM_EXISTS' as ExpectedStreamVersionGeneral;\nexport const STREAM_DOES_NOT_EXIST =\n 'STREAM_DOES_NOT_EXIST' as ExpectedStreamVersionGeneral;\nexport const NO_CONCURRENCY_CHECK =\n 'NO_CONCURRENCY_CHECK' as ExpectedStreamVersionGeneral;\n\nexport const matchesExpectedVersion = <\n StreamVersion = DefaultStreamVersionType,\n>(\n current: StreamVersion | undefined,\n expected: ExpectedStreamVersion<StreamVersion>,\n): boolean => {\n if (expected === NO_CONCURRENCY_CHECK) return true;\n\n if (expected == STREAM_DOES_NOT_EXIST) return current === undefined;\n\n if (expected == STREAM_EXISTS) return current !== undefined;\n\n return current === expected;\n};\n\nexport const assertExpectedVersionMatchesCurrent = <\n StreamVersion = DefaultStreamVersionType,\n>(\n current: StreamVersion | undefined,\n expected: ExpectedStreamVersion<StreamVersion> | undefined,\n): void => {\n expected ??= NO_CONCURRENCY_CHECK;\n\n if (!matchesExpectedVersion(current, expected))\n throw new ExpectedVersionConflictError(current, expected);\n};\n\nexport class ExpectedVersionConflictError<\n VersionType = DefaultStreamVersionType,\n> extends ConcurrencyError {\n constructor(\n current: VersionType | undefined,\n expected: ExpectedStreamVersion<VersionType>,\n ) {\n super(current?.toString(), expected?.toString());\n\n // 👇️ because we are extending a built-in class\n Object.setPrototypeOf(this, ExpectedVersionConflictError.prototype);\n }\n}\n","import retry from 'async-retry';\nimport {\n ReadableStream,\n ReadableStreamDefaultReader,\n TransformStream,\n TransformStreamDefaultController,\n} from 'web-streams-polyfill';\nimport type { Decoder } from './decoders';\nimport { DefaultDecoder } from './decoders/composite';\n\nexport const restream = <\n Source = unknown,\n Transformed = Source,\n StreamType = object,\n>(\n createSourceStream: () => ReadableStream<StreamType>,\n transform: (input: Source) => Transformed = (source) =>\n source as unknown as Transformed,\n retryOptions: retry.Options = { forever: true, minTimeout: 25 },\n decoder: Decoder<StreamType, Source> = new DefaultDecoder<Source>(),\n): ReadableStream<Transformed> =>\n new TransformStream<Source, Transformed>({\n start(controller) {\n retry(\n () => onRestream(createSourceStream, controller, transform, decoder),\n retryOptions,\n ).catch((error) => {\n controller.error(error);\n });\n },\n }).readable;\n\nconst onRestream = async <StreamType, Source, Transformed = Source>(\n createSourceStream: () => ReadableStream<StreamType>,\n controller: TransformStreamDefaultController<Transformed>,\n transform: (input: Source) => Transformed,\n decoder: Decoder<StreamType, Source>,\n): Promise<void> => {\n const sourceStream = createSourceStream();\n const reader = sourceStream.getReader();\n try {\n let done: boolean;\n\n do {\n done = await restreamChunk(reader, controller, transform, decoder);\n } while (!done);\n } finally {\n reader.releaseLock();\n }\n};\n\nconst restreamChunk = async <StreamType, Source, Transformed = Source>(\n reader: ReadableStreamDefaultReader<StreamType>,\n controller: TransformStreamDefaultController<Transformed>,\n transform: (input: Source) => Transformed,\n decoder: Decoder<StreamType, Source>,\n): Promise<boolean> => {\n const { done: isDone, value } = await reader.read();\n\n if (value) decoder.addToBuffer(value);\n\n if (!isDone && !decoder.hasCompleteMessage()) return false;\n\n decodeAndTransform(decoder, transform, controller);\n\n if (isDone) {\n controller.terminate();\n }\n\n return isDone;\n};\n\nconst decodeAndTransform = <StreamType, Source, Transformed = Source>(\n decoder: Decoder<StreamType, Source>,\n transform: (input: Source) => Transformed,\n controller: TransformStreamDefaultController<Transformed>,\n) => {\n try {\n const decoded = decoder.decode();\n if (!decoded) return;\n\n const transformed = transform(decoded);\n controller.enqueue(transformed);\n } catch (error) {\n controller.error(new Error(`Decoding error: ${error?.toString()}`));\n }\n};\n","import { v4 as randomUUID } from 'uuid';\nimport type {\n Event,\n ReadEvent,\n ReadEventMetadataWithGlobalPosition,\n} from '../typing';\nimport {\n type AggregateStreamOptions,\n type AggregateStreamResult,\n type AppendToStreamOptions,\n type AppendToStreamResult,\n type DefaultStreamVersionType,\n type EventStore,\n type ReadStreamOptions,\n type ReadStreamResult,\n} from './eventStore';\nimport { assertExpectedVersionMatchesCurrent } from './expectedVersion';\n\nexport type EventHandler<E extends Event = Event> = (\n eventEnvelope: ReadEvent<E>,\n) => void;\n\nexport const getInMemoryEventStore = (): EventStore<\n DefaultStreamVersionType,\n ReadEventMetadataWithGlobalPosition\n> => {\n const streams = new Map<string, ReadEvent[]>();\n\n const getAllEventsCount = () => {\n return Array.from<ReadEvent[]>(streams.values())\n .map((s) => s.length)\n .reduce((p, c) => p + c, 0);\n };\n\n return {\n async aggregateStream<State, EventType extends Event>(\n streamName: string,\n options: AggregateStreamOptions<State, EventType>,\n ): Promise<AggregateStreamResult<State> | null> {\n const { evolve, initialState, read } = options;\n\n const result = await this.readStream<EventType>(streamName, read);\n\n if (!result) return null;\n\n const events = result?.events ?? [];\n\n return {\n currentStreamVersion: BigInt(events.length),\n state: events.reduce(evolve, initialState()),\n };\n },\n\n readStream: <EventType extends Event>(\n streamName: string,\n options?: ReadStreamOptions,\n ): Promise<\n ReadStreamResult<\n EventType,\n DefaultStreamVersionType,\n ReadEventMetadataWithGlobalPosition\n >\n > => {\n const events = streams.get(streamName);\n const currentStreamVersion = events ? BigInt(events.length) : undefined;\n\n assertExpectedVersionMatchesCurrent(\n currentStreamVersion,\n options?.expectedStreamVersion,\n );\n\n const from = Number(options && 'from' in options ? options.from : 0);\n const to = Number(\n options && 'to' in options\n ? options.to\n : options && 'maxCount' in options && options.maxCount\n ? options.from + options.maxCount\n : events?.length ?? 1,\n );\n\n const resultEvents =\n events && events.length > 0\n ? events\n .map(\n (e) =>\n e as ReadEvent<\n EventType,\n ReadEventMetadataWithGlobalPosition\n >,\n )\n .slice(from, to)\n : [];\n\n const result: ReadStreamResult<\n EventType,\n DefaultStreamVersionType,\n ReadEventMetadataWithGlobalPosition\n > =\n events && events.length > 0\n ? {\n currentStreamVersion: currentStreamVersion!,\n events: resultEvents,\n }\n : null;\n\n return Promise.resolve(result);\n },\n\n appendToStream: <EventType extends Event>(\n streamName: string,\n events: EventType[],\n options?: AppendToStreamOptions,\n ): Promise<AppendToStreamResult> => {\n const currentEvents = streams.get(streamName) ?? [];\n const currentStreamVersion =\n currentEvents.length > 0 ? BigInt(currentEvents.length) : undefined;\n\n assertExpectedVersionMatchesCurrent(\n currentStreamVersion,\n options?.expectedStreamVersion,\n );\n\n const eventEnvelopes: ReadEvent<\n EventType,\n ReadEventMetadataWithGlobalPosition\n >[] = events.map((event, index) => {\n return {\n ...event,\n metadata: {\n ...(event.metadata ?? {}),\n streamName,\n eventId: randomUUID(),\n streamPosition: BigInt(currentEvents.length + index + 1),\n globalPosition: BigInt(getAllEventsCount() + index + 1),\n },\n };\n });\n\n const positionOfLastEventInTheStream = BigInt(\n eventEnvelopes.slice(-1)[0]!.metadata.streamPosition,\n );\n\n streams.set(streamName, [...currentEvents, ...eventEnvelopes]);\n\n const result: AppendToStreamResult = {\n nextExpectedStreamVersion: positionOfLastEventInTheStream,\n };\n\n return Promise.resolve(result);\n },\n };\n};\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkSS2LQM3Bjs = require('./chunk-SS2LQM3B.js');var
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkSS2LQM3Bjs = require('./chunk-SS2LQM3B.js');var _chunkQB7BC56Wjs = require('./chunk-QB7BC56W.js');var _dumbo = require('@event-driven-io/dumbo');var _uuid = require('uuid');var D=_dumbo.rawSql.call(void 0, `CREATE OR REPLACE FUNCTION emt_append_event(
|
|
2
2
|
v_event_ids text[],
|
|
3
3
|
v_events_data jsonb[],
|
|
4
4
|
v_events_metadata jsonb[],
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
RETURN QUERY SELECT TRUE, v_next_stream_position, v_last_global_position, v_transaction_id;
|
|
81
81
|
END;
|
|
82
82
|
$$;
|
|
83
|
-
`),h= exports.b =(t,a,r,n,i)=>t.withTransaction(async e=>{let{execute:x}=e;if(n.length===0)return{success:!1,result:{success:!1}};let p;try{let o=y(_optionalChain([i, 'optionalAccess', _2 => _2.expectedStreamVersion])),c=n.map((u,L)=>({...u,metadata:{streamName:a,eventId:_uuid.v4.call(void 0, ),streamPosition:BigInt(L),...u.metadata}}));p=await C(x,a,r,c,{expectedStreamVersion:o}),_optionalChain([i, 'optionalAccess', _3 => _3.preCommitHook])&&await i.preCommitHook(e
|
|
83
|
+
`),h= exports.b =(t,a,r,n,i)=>t.withTransaction(async e=>{let{execute:x}=e;if(n.length===0)return{success:!1,result:{success:!1}};let p;try{let o=y(_optionalChain([i, 'optionalAccess', _2 => _2.expectedStreamVersion])),c=n.map((u,L)=>({...u,metadata:{streamName:a,eventId:_uuid.v4.call(void 0, ),streamPosition:BigInt(L),...u.metadata}}));p=await C(x,a,r,c,{expectedStreamVersion:o}),_optionalChain([i, 'optionalAccess', _3 => _3.preCommitHook])&&await i.preCommitHook(c,{transaction:e})}catch(o){if(!f(o))throw o;p={success:!1,last_global_position:null,next_stream_position:null,transaction_id:null}}let{success:d,next_stream_position:m,last_global_position:l,transaction_id:E}=p;return{success:d,result:d&&m&&l&&E?{success:!0,nextStreamPosition:BigInt(m),lastGlobalPosition:BigInt(l),transactionId:E}:{success:!1}}}),y=t=>t===void 0||t===_chunkQB7BC56Wjs.n||t==_chunkQB7BC56Wjs.m||t==_chunkQB7BC56Wjs.l?null:t,f=t=>t instanceof Error&&"code"in t&&t.code==="23505",C=(t,a,r,n,i)=>_dumbo.single.call(void 0, t.command(_dumbo.sql.call(void 0, `SELECT * FROM emt_append_event(
|
|
84
84
|
ARRAY[%s]::text[],
|
|
85
85
|
ARRAY[%s]::jsonb[],
|
|
86
86
|
ARRAY[%s]::jsonb[],
|
|
@@ -90,5 +90,5 @@
|
|
|
90
90
|
%L::text,
|
|
91
91
|
%s::bigint,
|
|
92
92
|
%L::text
|
|
93
|
-
)`,n.map(e=>_dumbo.sql.call(void 0, "%L",e.metadata.eventId)).join(","),n.map(e=>_dumbo.sql.call(void 0, "%L",
|
|
94
|
-
//# sourceMappingURL=chunk-
|
|
93
|
+
)`,n.map(e=>_dumbo.sql.call(void 0, "%L",e.metadata.eventId)).join(","),n.map(e=>_dumbo.sql.call(void 0, "%L",_chunkQB7BC56Wjs.a.stringify(e.data))).join(","),n.map(e=>_dumbo.sql.call(void 0, "%L",_chunkQB7BC56Wjs.a.stringify(_nullishCoalesce(e.metadata, () => ({}))))).join(","),n.map(()=>"'1'").join(","),n.map(e=>_dumbo.sql.call(void 0, "%L",e.type)).join(","),a,r,_nullishCoalesce(_optionalChain([i, 'optionalAccess', _4 => _4.expectedStreamVersion]), () => ("NULL")),_nullishCoalesce(_optionalChain([i, 'optionalAccess', _5 => _5.partition]), () => (_chunkSS2LQM3Bjs.c)))));exports.a = D; exports.b = h;
|
|
94
|
+
//# sourceMappingURL=chunk-R5KGCWKQ.js.map
|