@jskit-ai/agent-docs 0.1.59 → 0.1.60

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.
@@ -124,6 +124,79 @@ So the mental model is:
124
124
  - `realtime` gives the app a live transport
125
125
  - your own app code, or later packages, decide which events should travel across it
126
126
 
127
+ ## Publishing server events
128
+
129
+ Server code should publish realtime lifecycle events through JSKIT's entity-change helpers instead of hand-rolling `domainEvents.publish()` payloads.
130
+
131
+ Keep `operation` limited to resource invalidation semantics:
132
+
133
+ - `created`
134
+ - `updated`
135
+ - `deleted`
136
+
137
+ Use `action` for the domain lifecycle transition, and `reason` only when you need to explain why that transition happened.
138
+
139
+ For direct publishers, use `createRealtimeEntityChangePublisher()` from `@jskit-ai/kernel/server/runtime/entityChangeEvents`:
140
+
141
+ ```js
142
+ import { createRealtimeEntityChangePublisher } from "@jskit-ai/kernel/server/runtime/entityChangeEvents";
143
+
144
+ const publishProjectRuntimeChanged = createRealtimeEntityChangePublisher({
145
+ domainEvents,
146
+ source: "vibe64",
147
+ entity: "project",
148
+ event: "vibe64.project.changed",
149
+ serviceToken: "vibe64.terminals.service",
150
+ methodName: "projectRuntime"
151
+ });
152
+
153
+ await publishProjectRuntimeChanged("updated", projectSlug, {
154
+ action: "runtime-closed",
155
+ payload: {
156
+ message: "Project is closed.",
157
+ runtime: {
158
+ open: false
159
+ }
160
+ }
161
+ });
162
+ ```
163
+
164
+ The helper emits a normal `entity.changed` domain event with service metadata and `meta.realtime.event`. The realtime bridge uses that service metadata to find the registered socket dispatcher, then emits the socket event with canonical fields such as `source`, `entity`, `operation`, `entityId`, `scope`, and the lifecycle `action`.
165
+
166
+ For services registered through `app.service()`, declare the same semantics in service metadata:
167
+
168
+ ```js
169
+ app.service(
170
+ "vibe64.terminals.service",
171
+ (scope) => createTerminalsService({
172
+ repository: scope.make("vibe64.repository.terminals")
173
+ }),
174
+ {
175
+ events: {
176
+ projectRuntime: [
177
+ {
178
+ type: "entity.changed",
179
+ source: "vibe64",
180
+ entity: "project",
181
+ operation: "updated",
182
+ entityId: ({ args }) => args?.[0]?.projectSlug,
183
+ action: "runtime-closed",
184
+ realtime: {
185
+ event: "vibe64.project.changed",
186
+ payload: ({ result }) => ({
187
+ message: result?.message || "",
188
+ runtime: result?.runtime || null
189
+ })
190
+ }
191
+ }
192
+ ]
193
+ }
194
+ }
195
+ );
196
+ ```
197
+
198
+ `action`, `reason`, and `realtime.payload` may be functions when the value depends on the service result or arguments. Do not encode lifecycle names by widening `operation`; keep `operation` truthful for CRUD/resource contracts and put domain-specific lifecycle meaning in metadata.
199
+
127
200
  ## What `realtime` adds to the app
128
201
 
129
202
  This chapter is small enough that it is worth looking directly at the app-owned files it changes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/agent-docs",
3
- "version": "0.1.59",
3
+ "version": "0.1.60",
4
4
  "description": "Distributed JSKIT agent references, prompts, guides, and generated reference maps.",
5
5
  "type": "module",
6
6
  "files": [
@@ -1163,6 +1163,7 @@ Local functions
1163
1163
  - `normalizeServiceEventType(value, { context = "service event" } = {})`
1164
1164
  - `normalizeServiceEventOperation(value, { context = "service event" } = {})`
1165
1165
  - `normalizeServiceEventEntityId(value)`
1166
+ - `normalizeServiceEventMetaField(value, { context = "service event meta field" } = {})`
1166
1167
  - `normalizeRealtimeDispatch(value, { context = "service event.realtime" } = {})`
1167
1168
  - `normalizeRealtimeAudience(value, { context = "service event.realtime.audience" } = {})`
1168
1169
  - `normalizeServiceEventSpec(entry, { context = "service event" } = {})`
@@ -1171,6 +1172,7 @@ Local functions
1171
1172
  - `resolveMethodOptions(args = [])`
1172
1173
  - `resolveEventOperation(spec, state)`
1173
1174
  - `resolveEventEntityId(spec, state)`
1175
+ - `resolveEventMetaField(value, state)`
1174
1176
  - `resolveEventMeta(spec, state)`
1175
1177
  - `createServiceMethodEventPublisher(scope, serviceToken, methodName, specs = [])`
1176
1178
 
@@ -1217,12 +1219,17 @@ Exports
1217
1219
  Exports
1218
1220
  - `resolveDefaultScope(visibilityContext = {}, runtime = {})`
1219
1221
  - `createEntityChangePublisher({ domainEvents, source, entity, scopeResolver = resolveDefaultScope } = {})`
1222
+ - `createRealtimeEntityChangePublisher({ domainEvents, source, entity, event, serviceToken, methodName, scopeResolver = resolveDefaultScope } = {})`
1220
1223
  - `createNoopEntityChangePublisher()`
1221
1224
  Local functions
1222
1225
  - `resolveContextScope(context = {})`
1223
1226
  - `resolveVisibilityScope(visibilityContext = {}, runtimeContext = {})`
1224
1227
  - `resolveCommandId(requestMeta = {})`
1225
1228
  - `resolveSourceClientId(requestMeta = {})`
1229
+ - `normalizeMetaTextField(source = {}, fieldName = "", { context = "realtime entity change" } = {})`
1230
+ - `normalizeRealtimePayload(value, { context = "realtime entity change.payload" } = {})`
1231
+ - `createRealtimeEntityChangeMeta({ serviceToken, methodName, event, change = {} } = {})`
1232
+ - `resolveRealtimeEntityChangeOptions(change = {}, options = {})`
1226
1233
 
1227
1234
  ### `server/runtime/errors.js`
1228
1235
  Exports