@ossy/event-store 3.0.2 → 3.0.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ossy/event-store",
3
- "version": "3.0.2",
3
+ "version": "3.0.4",
4
4
  "description": "Ossy Event Store — Aggregate, EventStore, and MongoDB client",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,8 +25,8 @@
25
25
  "author": "Ossy <yourfriends@ossy.se> (https://ossy.se)",
26
26
  "license": "MIT",
27
27
  "dependencies": {
28
- "@ossy/fold": "^3.0.2",
29
- "@ossy/observability": "^3.0.2",
28
+ "@ossy/fold": "^3.0.4",
29
+ "@ossy/observability": "^3.0.4",
30
30
  "mongodb": "^7.2.0",
31
31
  "nanoid": "^5.1.11"
32
32
  },
@@ -37,5 +37,5 @@
37
37
  "files": [
38
38
  "src"
39
39
  ],
40
- "gitHead": "f0a8af3c370bbaffe4f7388c14f9345a5c6c56e5"
40
+ "gitHead": "831c9816bee67c5e53d0a4be4f6401975f23d72a"
41
41
  }
@@ -1,4 +1,7 @@
1
- import { AggregateRebuild } from './aggregate-rebuild.js'
1
+ // Import via package entry so Rollup keeps `@ossy/event-store` external.
2
+ // A relative import would bundle a second AggregateRebuild with an empty
3
+ // `_schemaMap`, so changestream rebuilds ignore domain events (e.g. ServiceEnabled).
4
+ import { AggregateRebuild } from '@ossy/event-store'
2
5
 
3
6
  /** Platform audit envelopes have no entity aggregate snapshot — handled inline on the changestream. */
4
7
  const PLATFORM_AUDIT_TYPES = [
@@ -1,5 +1,5 @@
1
1
  import { withMongoReconnect } from './mongodb.js'
2
- import { ProjectionRebuild } from './projection-rebuild.js'
2
+ import { ProjectionRebuild, projectionDocumentId } from './projection-rebuild.js'
3
3
 
4
4
  /**
5
5
  * Load a projection snapshot by scope id and projection type id.
@@ -10,8 +10,9 @@ import { ProjectionRebuild } from './projection-rebuild.js'
10
10
  */
11
11
  export async function getProjection (scopeId, projectionId) {
12
12
  if (!scopeId || !projectionId) return null
13
+ const docId = projectionDocumentId(projectionId, scopeId)
13
14
  const doc = await withMongoReconnect(() =>
14
- ProjectionRebuild.Collection.findOne({ id: scopeId, type: projectionId }),
15
+ ProjectionRebuild.Collection.findOne({ id: docId }),
15
16
  )
16
17
  return doc?.state ?? null
17
18
  }
@@ -5,6 +5,18 @@ import { createLogger } from '@ossy/observability'
5
5
 
6
6
  const log = createLogger('event-store')
7
7
 
8
+ /**
9
+ * Document id for projection snapshots — must not collide with entity resourceIds
10
+ * (aggregates collection has a unique index on `id`).
11
+ *
12
+ * @param {string} projectionId
13
+ * @param {string} scopeId
14
+ * @returns {string}
15
+ */
16
+ export function projectionDocumentId (projectionId, scopeId) {
17
+ return `${projectionId}:${scopeId}`
18
+ }
19
+
8
20
  /**
9
21
  * ADR 0008 projection aggregate rebuild — derived read models keyed by `scopeId`.
10
22
  */
@@ -82,15 +94,17 @@ export class ProjectionRebuild {
82
94
  const version = scopeEvents.length
83
95
  const last = scopeEvents[scopeEvents.length - 1]
84
96
  const cursor = last ? { eventId: last.id, eventVersion: last.version } : null
97
+ const docId = projectionDocumentId(ProjectionClass.ProjectionId, scopeId)
85
98
 
86
99
  await withMongoReconnect(() =>
87
100
  ProjectionRebuild.Collection.updateOne(
88
- { id: scopeId, type: ProjectionClass.ProjectionId },
101
+ { id: docId },
89
102
  {
90
103
  $set: {
91
- id: scopeId,
104
+ id: docId,
92
105
  type: ProjectionClass.ProjectionId,
93
106
  kind: 'projection',
107
+ scopeId,
94
108
  version,
95
109
  state: { ...state, version, cursor },
96
110
  },
@@ -106,8 +120,9 @@ export class ProjectionRebuild {
106
120
 
107
121
  static async _applyOne (ProjectionClass, scopeId, event) {
108
122
  const projectionId = ProjectionClass.ProjectionId
123
+ const docId = projectionDocumentId(projectionId, scopeId)
109
124
  const snapshot = await withMongoReconnect(() =>
110
- ProjectionRebuild.Collection.findOne({ id: scopeId, type: projectionId }),
125
+ ProjectionRebuild.Collection.findOne({ id: docId }),
111
126
  )
112
127
 
113
128
  const state = snapshot?.state ?? ProjectionClass.initialState?.(scopeId) ?? {}
@@ -119,12 +134,13 @@ export class ProjectionRebuild {
119
134
 
120
135
  await withMongoReconnect(() =>
121
136
  ProjectionRebuild.Collection.updateOne(
122
- { id: scopeId, type: projectionId },
137
+ { id: docId },
123
138
  {
124
139
  $set: {
125
- id: scopeId,
140
+ id: docId,
126
141
  type: projectionId,
127
142
  kind: 'projection',
143
+ scopeId,
128
144
  version,
129
145
  state: { ...next, version, cursor },
130
146
  },