@event-driven-io/emmett 0.42.0-beta.1 → 0.42.0-beta.3

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/index.js CHANGED
@@ -84,6 +84,12 @@ var accept = () => {
84
84
  return { action: "Accept" };
85
85
  };
86
86
 
87
+ // src/typing/index.ts
88
+ var emmettPrefix = "emt";
89
+ var globalTag = "global";
90
+ var defaultTag = `${emmettPrefix}:default`;
91
+ var unknownTag = `${emmettPrefix}:unknown`;
92
+
87
93
  // src/eventStore/afterCommit/afterEventStoreCommitHandler.ts
88
94
  async function tryPublishMessagesAfterCommit(messages, options, context) {
89
95
  if (options?.onAfterCommit === void 0) return false;
@@ -586,6 +592,12 @@ var InProcessLock = () => {
586
592
  };
587
593
  };
588
594
 
595
+ // src/utils/numbers/bigint.ts
596
+ var toNormalizedString = (value) => value.toString().padStart(19, "0");
597
+ var bigInt = {
598
+ toNormalizedString
599
+ };
600
+
589
601
  // src/utils/promises.ts
590
602
  var delay = (ms) => {
591
603
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -653,6 +665,17 @@ var asyncRetry = async (fn, opts) => {
653
665
  );
654
666
  };
655
667
 
668
+ // src/utils/strings/hashText.ts
669
+ var textEncoder = new TextEncoder();
670
+ var hashText = async (text) => {
671
+ const hashBuffer = await crypto.subtle.digest(
672
+ "SHA-256",
673
+ textEncoder.encode(text)
674
+ );
675
+ const view = new BigInt64Array(hashBuffer, 0, 1);
676
+ return view[0];
677
+ };
678
+
656
679
  // src/database/utils.ts
657
680
  var isGeneralExpectedDocumentVersion = (version) => {
658
681
  return version === "DOCUMENT_DOES_NOT_EXIST" || version === "DOCUMENT_EXISTS" || version === "NO_CONCURRENCY_CHECK";
@@ -1429,6 +1452,9 @@ var InMemoryProjectionSpec = {
1429
1452
  nextExpectedStreamVersion: 0n,
1430
1453
  createdNewStream: false
1431
1454
  });
1455
+ },
1456
+ streamExists: async () => {
1457
+ return Promise.resolve(false);
1432
1458
  }
1433
1459
  };
1434
1460
  await handleInMemoryProjections({
@@ -1617,6 +1643,10 @@ var getInMemoryEventStore = (eventStoreOptions) => {
1617
1643
  eventStoreOptions?.hooks
1618
1644
  );
1619
1645
  return result;
1646
+ },
1647
+ streamExists: (streamName) => {
1648
+ const events = streams.get(streamName);
1649
+ return Promise.resolve(events !== void 0 && events.length > 0);
1620
1650
  }
1621
1651
  };
1622
1652
  return eventStore;
@@ -1782,6 +1812,7 @@ var getInMemoryMessageBus = () => {
1782
1812
  };
1783
1813
 
1784
1814
  // src/processors/processors.ts
1815
+ import { v7 as uuid4 } from "uuid";
1785
1816
  var getCheckpoint = (message2) => {
1786
1817
  return "checkpoint" in message2.metadata ? (
1787
1818
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
@@ -1818,28 +1849,58 @@ var MessageProcessor = {
1818
1849
  }
1819
1850
  };
1820
1851
  var defaultProcessingMessageProcessingScope = (handler, partialContext) => handler(partialContext);
1852
+ var defaultProcessorVersion = 1;
1853
+ var defaultProcessorPartition = defaultTag;
1854
+ var getProcessorInstanceId = (processorId) => `${processorId}:${uuid4()}`;
1855
+ var getProjectorId = (options) => `emt:processor:projector:${options.projectionName}`;
1821
1856
  var reactor = (options) => {
1857
+ const {
1858
+ checkpoints,
1859
+ processorId,
1860
+ processorInstanceId: instanceId = getProcessorInstanceId(processorId),
1861
+ type = MessageProcessorType.REACTOR,
1862
+ version = defaultProcessorVersion,
1863
+ partition = defaultProcessorPartition,
1864
+ hooks = {},
1865
+ processingScope = defaultProcessingMessageProcessingScope,
1866
+ startFrom,
1867
+ canHandle,
1868
+ stopAfter
1869
+ } = options;
1822
1870
  const eachMessage = "eachMessage" in options && options.eachMessage ? options.eachMessage : () => Promise.resolve();
1823
- let isActive = true;
1824
- const { checkpoints, processorId, partition } = options;
1825
- const processingScope = options.processingScope ?? defaultProcessingMessageProcessingScope;
1871
+ let isInitiated = false;
1872
+ let isActive = false;
1826
1873
  let lastCheckpoint = null;
1874
+ const init = async (initOptions) => {
1875
+ if (isInitiated) return;
1876
+ if (hooks.onInit === void 0) {
1877
+ isInitiated = true;
1878
+ return;
1879
+ }
1880
+ return await processingScope(async (context) => {
1881
+ await hooks.onInit(context);
1882
+ isInitiated = true;
1883
+ }, initOptions);
1884
+ };
1827
1885
  return {
1828
- id: options.processorId,
1829
- type: options.type ?? MessageProcessorType.REACTOR,
1830
- close: () => options.hooks?.onClose ? options.hooks?.onClose() : Promise.resolve(),
1886
+ // TODO: Consider whether not make it optional or add URN prefix
1887
+ id: processorId,
1888
+ instanceId,
1889
+ type,
1890
+ init,
1831
1891
  start: async (startOptions) => {
1892
+ if (isActive) return;
1893
+ await init(startOptions);
1832
1894
  isActive = true;
1833
1895
  if (lastCheckpoint !== null)
1834
1896
  return {
1835
1897
  lastCheckpoint
1836
1898
  };
1837
1899
  return await processingScope(async (context) => {
1838
- if (options.hooks?.onStart) {
1839
- await options.hooks?.onStart(context);
1900
+ if (hooks.onStart) {
1901
+ await hooks.onStart(context);
1840
1902
  }
1841
- if (options.startFrom !== "CURRENT" && options.startFrom)
1842
- return options.startFrom;
1903
+ if (startFrom && startFrom !== "CURRENT") return startFrom;
1843
1904
  if (checkpoints) {
1844
1905
  const readResult = await checkpoints?.read(
1845
1906
  {
@@ -1856,6 +1917,7 @@ var reactor = (options) => {
1856
1917
  };
1857
1918
  }, startOptions);
1858
1919
  },
1920
+ close: hooks?.onClose ? async (closeOptions) => await processingScope(hooks.onClose, closeOptions) : () => Promise.resolve(),
1859
1921
  get isActive() {
1860
1922
  return isActive;
1861
1923
  },
@@ -1865,15 +1927,17 @@ var reactor = (options) => {
1865
1927
  let result = void 0;
1866
1928
  for (const message2 of messages) {
1867
1929
  if (wasMessageHandled(message2, lastCheckpoint)) continue;
1930
+ if (canHandle !== void 0 && !canHandle.includes(message2.type))
1931
+ return;
1868
1932
  const messageProcessingResult = await eachMessage(message2, context);
1869
1933
  if (checkpoints) {
1870
1934
  const storeCheckpointResult = await checkpoints.store(
1871
1935
  {
1872
- processorId: options.processorId,
1873
- version: options.version,
1936
+ processorId,
1937
+ version,
1874
1938
  message: message2,
1875
1939
  lastCheckpoint,
1876
- partition: options.partition
1940
+ partition
1877
1941
  },
1878
1942
  context
1879
1943
  );
@@ -1886,7 +1950,7 @@ var reactor = (options) => {
1886
1950
  result = messageProcessingResult;
1887
1951
  break;
1888
1952
  }
1889
- if (options.stopAfter && options.stopAfter(message2)) {
1953
+ if (stopAfter && stopAfter(message2)) {
1890
1954
  isActive = false;
1891
1955
  result = { type: "STOP", reason: "Stop condition reached" };
1892
1956
  break;
@@ -1900,12 +1964,20 @@ var reactor = (options) => {
1900
1964
  };
1901
1965
  };
1902
1966
  var projector = (options) => {
1903
- const { projection: projection2, ...rest } = options;
1967
+ const {
1968
+ projection: projection2,
1969
+ processorId = getProjectorId({
1970
+ projectionName: projection2.name ?? "unknown"
1971
+ }),
1972
+ ...rest
1973
+ } = options;
1904
1974
  return reactor({
1905
1975
  ...rest,
1906
1976
  type: MessageProcessorType.PROJECTOR,
1907
- processorId: options.processorId ?? `projection:${projection2.name}`,
1977
+ canHandle: projection2.canHandle,
1978
+ processorId,
1908
1979
  hooks: {
1980
+ onInit: options.hooks?.onInit,
1909
1981
  onStart: options.truncateOnStart && options.projection.truncate || options.hooks?.onStart ? async (context) => {
1910
1982
  if (options.truncateOnStart && options.projection.truncate)
1911
1983
  await options.projection.truncate(context);
@@ -1913,10 +1985,7 @@ var projector = (options) => {
1913
1985
  } : void 0,
1914
1986
  onClose: options.hooks?.onClose
1915
1987
  },
1916
- eachMessage: async (event2, context) => {
1917
- if (!projection2.canHandle.includes(event2.type)) return;
1918
- await projection2.handle([event2], context);
1919
- }
1988
+ eachMessage: async (event2, context) => projection2.handle([event2], context)
1920
1989
  });
1921
1990
  };
1922
1991
 
@@ -1942,7 +2011,7 @@ var inMemoryCheckpointer = () => {
1942
2011
  if (currentPosition && (currentPosition === newCheckpoint || currentPosition !== lastCheckpoint)) {
1943
2012
  return {
1944
2013
  success: false,
1945
- reason: currentPosition === newCheckpoint ? "IGNORED" : "MISMATCH"
2014
+ reason: currentPosition === newCheckpoint ? "IGNORED" : newCheckpoint !== null && currentPosition > newCheckpoint ? "CURRENT_AHEAD" : "MISMATCH"
1946
2015
  };
1947
2016
  }
1948
2017
  await checkpoints.handle(processorId, (existing) => ({
@@ -1969,44 +2038,40 @@ var inMemoryProcessingScope = (options) => {
1969
2038
  var inMemoryProjector = (options) => {
1970
2039
  const database = options.connectionOptions?.database ?? getInMemoryDatabase();
1971
2040
  const hooks = {
2041
+ onInit: options.hooks?.onInit,
1972
2042
  onStart: options.hooks?.onStart,
1973
- onClose: options.hooks?.onClose ? async () => {
1974
- if (options.hooks?.onClose) await options.hooks?.onClose();
2043
+ onClose: options.hooks?.onClose ? async (context) => {
2044
+ if (options.hooks?.onClose) await options.hooks?.onClose(context);
1975
2045
  } : void 0
1976
2046
  };
1977
- return {
1978
- ...projector({
1979
- ...options,
1980
- hooks,
1981
- processingScope: inMemoryProcessingScope({
1982
- database,
1983
- processorId: options.processorId ?? `projection:${options.projection.name}`
1984
- }),
1985
- checkpoints: inMemoryCheckpointer()
2047
+ const processor = projector({
2048
+ ...options,
2049
+ hooks,
2050
+ processingScope: inMemoryProcessingScope({
2051
+ database,
2052
+ processorId: options.processorId ?? `projection:${options.projection.name}`
1986
2053
  }),
1987
- database
1988
- };
2054
+ checkpoints: inMemoryCheckpointer()
2055
+ });
2056
+ return Object.assign(processor, { database });
1989
2057
  };
1990
2058
  var inMemoryReactor = (options) => {
1991
2059
  const database = options.connectionOptions?.database ?? getInMemoryDatabase();
1992
2060
  const hooks = {
2061
+ onInit: options.hooks?.onInit,
1993
2062
  onStart: options.hooks?.onStart,
1994
- onClose: options.hooks?.onClose ? async () => {
1995
- if (options.hooks?.onClose) await options.hooks?.onClose();
1996
- } : void 0
2063
+ onClose: options.hooks?.onClose
1997
2064
  };
1998
- return {
1999
- ...reactor({
2000
- ...options,
2001
- hooks,
2002
- processingScope: inMemoryProcessingScope({
2003
- database,
2004
- processorId: options.processorId
2005
- }),
2006
- checkpoints: inMemoryCheckpointer()
2065
+ const processor = reactor({
2066
+ ...options,
2067
+ hooks,
2068
+ processingScope: inMemoryProcessingScope({
2069
+ database,
2070
+ processorId: options.processorId
2007
2071
  }),
2008
- database
2009
- };
2072
+ checkpoints: inMemoryCheckpointer()
2073
+ });
2074
+ return Object.assign(processor, { database });
2010
2075
  };
2011
2076
 
2012
2077
  // src/projections/index.ts
@@ -2095,14 +2160,19 @@ export {
2095
2160
  asyncAwaiter,
2096
2161
  asyncProjections,
2097
2162
  asyncRetry,
2163
+ bigInt,
2098
2164
  canCreateEventStoreSession,
2099
2165
  caughtUpEventFrom,
2100
2166
  command,
2101
2167
  complete,
2102
2168
  deepEquals,
2103
2169
  defaultProcessingMessageProcessingScope,
2170
+ defaultProcessorPartition,
2171
+ defaultProcessorVersion,
2172
+ defaultTag,
2104
2173
  delay,
2105
2174
  documentExists,
2175
+ emmettPrefix,
2106
2176
  error,
2107
2177
  event,
2108
2178
  eventInStream,
@@ -2115,8 +2185,12 @@ export {
2115
2185
  getInMemoryDatabase,
2116
2186
  getInMemoryEventStore,
2117
2187
  getInMemoryMessageBus,
2188
+ getProcessorInstanceId,
2189
+ getProjectorId,
2118
2190
  globalStreamCaughtUp,
2191
+ globalTag,
2119
2192
  handleInMemoryProjections,
2193
+ hashText,
2120
2194
  ignore,
2121
2195
  inMemoryCheckpointer,
2122
2196
  inMemoryMultiStreamProjection,
@@ -2152,7 +2226,9 @@ export {
2152
2226
  schedule,
2153
2227
  send,
2154
2228
  sum,
2229
+ toNormalizedString,
2155
2230
  tryPublishMessagesAfterCommit,
2231
+ unknownTag,
2156
2232
  verifyThat,
2157
2233
  wasMessageHandled
2158
2234
  };