@agentshouse/mdruntime 0.1.0-c8c4b020a3ec7 → 0.1.0-ca1eff92bbe73

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.
Files changed (70) hide show
  1. package/AGENTS.md +62 -26
  2. package/README.md +10 -10
  3. package/dist/adapter.d.ts +81 -43
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js +1 -9
  6. package/dist/attached-model.d.ts +11 -0
  7. package/dist/attached-model.d.ts.map +1 -0
  8. package/dist/attached-model.js +47 -0
  9. package/dist/bootstrap.d.ts +5 -3
  10. package/dist/bootstrap.d.ts.map +1 -1
  11. package/dist/bootstrap.js +3 -2
  12. package/dist/client.d.ts +3 -2
  13. package/dist/client.d.ts.map +1 -1
  14. package/dist/client.js +3 -10
  15. package/dist/connection.d.ts +10 -12
  16. package/dist/connection.d.ts.map +1 -1
  17. package/dist/connection.js +518 -516
  18. package/dist/conversation.d.ts +22 -11
  19. package/dist/conversation.d.ts.map +1 -1
  20. package/dist/conversation.js +250 -105
  21. package/dist/host.d.ts +7 -1
  22. package/dist/host.d.ts.map +1 -1
  23. package/dist/host.js +34 -31
  24. package/dist/index.d.ts +3 -3
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/memory.d.ts +11 -5
  27. package/dist/memory.d.ts.map +1 -1
  28. package/dist/memory.js +84 -26
  29. package/dist/model.d.ts +11 -11
  30. package/dist/model.d.ts.map +1 -1
  31. package/dist/model.js +6 -3
  32. package/dist/observation.d.ts +2 -0
  33. package/dist/observation.d.ts.map +1 -1
  34. package/dist/observation.js +24 -14
  35. package/dist/paths.d.ts +0 -1
  36. package/dist/paths.d.ts.map +1 -1
  37. package/dist/paths.js +0 -16
  38. package/dist/query.d.ts +8 -3
  39. package/dist/query.d.ts.map +1 -1
  40. package/dist/query.js +104 -36
  41. package/dist/reach.d.ts +40 -0
  42. package/dist/reach.d.ts.map +1 -0
  43. package/dist/reach.js +270 -0
  44. package/dist/react.d.ts +32 -0
  45. package/dist/react.d.ts.map +1 -0
  46. package/dist/react.js +62 -0
  47. package/dist/read-side.d.ts +4 -0
  48. package/dist/read-side.d.ts.map +1 -1
  49. package/dist/read-side.js +116 -54
  50. package/dist/refresh.d.ts +2 -1
  51. package/dist/refresh.d.ts.map +1 -1
  52. package/dist/refresh.js +7 -3
  53. package/dist/replica.d.ts +5 -5
  54. package/dist/replica.d.ts.map +1 -1
  55. package/dist/replica.js +14 -15
  56. package/dist/room-draft.d.ts +3 -0
  57. package/dist/room-draft.d.ts.map +1 -1
  58. package/dist/room-draft.js +6 -4
  59. package/dist/rows.d.ts +2 -1
  60. package/dist/rows.d.ts.map +1 -1
  61. package/dist/rows.js +75 -38
  62. package/dist/save.d.ts +1 -2
  63. package/dist/save.d.ts.map +1 -1
  64. package/dist/save.js +90 -48
  65. package/dist/store.d.ts +1 -1
  66. package/dist/store.d.ts.map +1 -1
  67. package/dist/wire.d.ts +51 -16
  68. package/dist/wire.d.ts.map +1 -1
  69. package/dist/wire.js +50 -59
  70. package/package.json +14 -2
package/dist/host.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { composeRuntime, } from './connection.js';
2
2
  import { removeRuntimeStore } from './store.js';
3
- import { AUTHORIZATION_ENDED, carried, envelope, PROTOCOL_MISMATCH, request, } from './wire.js';
3
+ import { AUTHORIZATION_ENDED, request, WIRE_REACH, } from './wire.js';
4
+ const NARROWED = new Set(['within', 'whole']);
4
5
  function answered(md, app, writtenBy, member, input) {
5
6
  switch (member) {
6
7
  case 'rooms':
@@ -71,57 +72,61 @@ export function serveMdRuntime(options) {
71
72
  if (options.signal?.aborted === true)
72
73
  close();
73
74
  const runtime = composeRuntime({ ...options, signal: closing.signal });
74
- const { md, watch } = runtime;
75
+ const { md } = runtime;
75
76
  const attachments = new Map();
76
77
  let authorized = true;
77
78
  const watchFacts = (deliver) => {
78
79
  deliver(structuredClone(deploymentFacts));
79
80
  return () => { };
80
81
  };
81
- function attach(port, app, release) {
82
+ function attach(port, app, release, reach) {
82
83
  if (!authorized)
83
84
  throw new Error(AUTHORIZATION_ENDED);
84
85
  const writtenBy = release === undefined ? undefined : { app, release };
85
- const subscriptions = new Map();
86
+ const view = runtime.within(reach ?? null);
87
+ const observations = new Map();
86
88
  let serving = true;
87
89
  const send = (message) => {
88
- port.postMessage(envelope(message));
90
+ port.postMessage(message);
89
91
  };
90
92
  const detach = () => {
91
93
  if (!serving)
92
94
  return;
93
95
  serving = false;
94
- for (const end of subscriptions.values())
96
+ for (const end of observations.values())
95
97
  end();
96
- subscriptions.clear();
98
+ observations.clear();
97
99
  attachments.delete(detach);
98
100
  };
101
+ const observe = (id, topic, input) => {
102
+ let resolved = false;
103
+ const deliver = (value) => {
104
+ if (!serving)
105
+ return;
106
+ send(resolved ? { kind: 'event', id, value } : { kind: 'result', id, value });
107
+ resolved = true;
108
+ };
109
+ observations.set(id, topic === 'deployment-facts'
110
+ ? watchFacts(deliver)
111
+ : (NARROWED.has(WIRE_REACH.topics[topic]) ? view : runtime).watch(topic, topic === 'presentation' ? [app] : input, deliver));
112
+ };
99
113
  const serve = async (message) => {
100
114
  if (message.kind === 'hello')
101
115
  return;
102
116
  if (message.kind === 'stop') {
103
- subscriptions.get(message.id)?.();
104
- subscriptions.delete(message.id);
117
+ observations.get(message.id)?.();
118
+ observations.delete(message.id);
105
119
  return;
106
120
  }
107
121
  try {
108
122
  if (message.kind !== 'observe' || message.topic !== 'room-drafts')
109
123
  await md.loaded();
110
124
  if (message.kind === 'observe') {
111
- const { id, topic } = message;
112
- let resolved = false;
113
- const deliver = (value) => {
114
- if (!serving)
115
- return;
116
- send(resolved ? { kind: 'event', id, value } : { kind: 'result', id, value });
117
- resolved = true;
118
- };
119
- subscriptions.set(id, topic === 'deployment-facts'
120
- ? watchFacts(deliver)
121
- : watch(topic, topic === 'presentation' ? [app] : message.input, deliver));
125
+ if (serving)
126
+ observe(message.id, message.topic, message.input);
122
127
  return;
123
128
  }
124
- const value = await answered(md, app, writtenBy, message.member, message.input);
129
+ const value = await answered(NARROWED.has(WIRE_REACH.members[message.member]) ? view.md : md, app, writtenBy, message.member, message.input);
125
130
  if (serving)
126
131
  send({ kind: 'result', id: message.id, value });
127
132
  }
@@ -138,15 +143,7 @@ export function serveMdRuntime(options) {
138
143
  port.addEventListener('message', (event) => {
139
144
  if (!serving)
140
145
  return;
141
- const wire = carried(event.data);
142
- if (wire === null)
143
- return;
144
- if (!wire.matching) {
145
- send({ kind: 'refusal', refusal: PROTOCOL_MISMATCH });
146
- detach();
147
- return;
148
- }
149
- const message = request(wire.message);
146
+ const message = request(event.data);
150
147
  if (message === null)
151
148
  return;
152
149
  void serve(message);
@@ -154,7 +151,13 @@ export function serveMdRuntime(options) {
154
151
  port.addEventListener('close', detach);
155
152
  port.start();
156
153
  attachments.set(detach, send);
157
- return detach;
154
+ return {
155
+ detach,
156
+ narrow(next) {
157
+ if (serving)
158
+ view.narrow(next);
159
+ },
160
+ };
158
161
  }
159
162
  return {
160
163
  attach,
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export type { AcceptedMessage, ActionDeclaration, ActionRequest, ActionResult, Adapter, AdapterFailure, Authorization, BootstrapPage, BootstrapRequest, BootstrapResult, Capability, ChangeAuthor, ContractUnavailable, ConversationAction, ConversationCards, ConversationEvent, ConversationHistories, ConversationHistoryPage, ConversationHistoryRequest, ConversationMessage, ConversationStream, DiscoverResult, DiscoveredRoom, Discovery, HistoryAuthor, HistoryRequest, HistoryResult, HistoryRetention, HistoryRevision, MdModelIdentity, ModelRequest, MutationRequest, MutationResult, PageToken, ProviderLimit, ProviderRefusal, RefreshPage, RefreshRequest, RefreshResult, Retention, RetryableRefusal, RevokedAuthorization, RoomAttachment, RoomNotReadable, RoomVersionAt, RoomVersionNotification, SelectedRooms, ServiceMode, ServiceModeSignal, TransportUncertainty, TypedSelection, WorkingNote, } from './adapter.js';
1
+ export type { AcceptedMessage, ActionDeclaration, ActionRequest, ActionResult, Adapter, AdapterFailure, Authorization, BootstrapPage, BootstrapRequest, BootstrapResult, Capability, ChangeAuthor, ContractUnavailable, ConversationAction, ConversationAgents, ConversationEvent, ConversationHistories, ConversationHistoryPage, ConversationHistoryRequest, ConversationMessage, ConversationStream, DiscoverResult, DiscoveredRoom, Discovery, HistoryAuthor, HistoryRequest, HistoryResult, HistoryRetention, HistoryRevision, HeldRoom, ListedConversation, MdModelIdentity, MutationRequest, MutationResult, PageToken, ProviderLimit, ProviderRefusal, RefreshPage, RefreshRequest, RefreshResult, Retention, RetryableRefusal, RevokedAuthorization, RoomAttachment, RoomModels, RoomNotReadable, RoomStream, RoomStreamEvent, RoomVersionAt, ServiceMode, ServiceModeSignal, TransportUncertainty, TurnContext, TurnOperation, TypedSelection, } from './adapter.js';
2
2
  export type { Change, ChangeBatch, Precondition, WrittenBy } from './change.js';
3
- export type { ChatDraft, ChatDraftSurface, ConversationEntry, ConversationOptions, ConversationSurface, ConversationView, GrowingText, } from './conversation.js';
3
+ export type { ChatDraft, ChatDraftSurface, ConversationEntry, ConversationOptions, ConversationState, ConversationSurface, ConversationView, RunningTurn, } from './conversation.js';
4
4
  export type { ChatDraftFile, FileDeclaration } from './file.js';
5
- export type { AppRoom, AppTypedSelection, ConnectionRefusal, ConnectionRefusalReason, HistoryQuery, MdRuntime, MdRuntimeOptions, PresentationSurface, RoomDraftSurface, RoomTypes, SavedRoomDraft, SaveResult, } from './connection.js';
5
+ export type { AppRoom, AppTypedSelection, ConnectionRefusal, ConnectionRefusalReason, HistoryQuery, MdRuntime, MdRuntimeOptions, PresentationSurface, RoomDraftSurface, RoomSchemas, SavedRoomDraft, SaveResult, } from './connection.js';
6
6
  export type { Observation } from './observation.js';
7
7
  export type { CallResult, QueueEntry, Submission } from './outcome.js';
8
8
  export type { ChangedPart, FieldValue, ReturnReason, RoomDraft, RoomDraftCreation, RoomDraftParts, RoomDraftWrite, } from './room-draft.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,OAAO,EACP,cAAc,EACd,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,SAAS,EACT,aAAa,EACb,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,eAAe,EACf,cAAc,EACd,SAAS,EACT,aAAa,EACb,eAAe,EACf,WAAW,EACX,cAAc,EACd,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,aAAa,EACb,uBAAuB,EACvB,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,cAAc,EACd,WAAW,GACZ,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAChF,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAChE,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,SAAS,EACT,cAAc,EACd,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACvE,YAAY,EACV,WAAW,EACX,UAAU,EACV,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,cAAc,EACd,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EACV,WAAW,EACX,YAAY,EACZ,UAAU,EACV,aAAa,EACb,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9D,YAAY,EACV,QAAQ,EACR,SAAS,EACT,aAAa,EACb,cAAc,EACd,MAAM,EACN,UAAU,EACV,WAAW,EACX,GAAG,EACH,UAAU,EACV,YAAY,EACZ,SAAS,EACT,aAAa,EACb,UAAU,EACV,WAAW,EACX,OAAO,EACP,MAAM,EACN,KAAK,EACL,KAAK,GACN,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,MAAM,EACN,aAAa,EACb,aAAa,EACb,UAAU,EACV,WAAW,EACX,WAAW,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,OAAO,EACP,cAAc,EACd,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,SAAS,EACT,aAAa,EACb,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,cAAc,EACd,SAAS,EACT,aAAa,EACb,eAAe,EACf,WAAW,EACX,cAAc,EACd,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,UAAU,EACV,eAAe,EACf,UAAU,EACV,eAAe,EACf,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,cAAc,GACf,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAChF,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAChE,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACvE,YAAY,EACV,WAAW,EACX,UAAU,EACV,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,cAAc,EACd,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EACV,WAAW,EACX,YAAY,EACZ,UAAU,EACV,aAAa,EACb,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9D,YAAY,EACV,QAAQ,EACR,SAAS,EACT,aAAa,EACb,cAAc,EACd,MAAM,EACN,UAAU,EACV,WAAW,EACX,GAAG,EACH,UAAU,EACV,YAAY,EACZ,SAAS,EACT,aAAa,EACb,UAAU,EACV,WAAW,EACX,OAAO,EACP,MAAM,EACN,KAAK,EACL,KAAK,GACN,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,MAAM,EACN,aAAa,EACb,aAAa,EACb,UAAU,EACV,WAAW,EACX,WAAW,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
package/dist/memory.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ModelResult } from './model.js';
2
- import { type AcceptedMessage, type ActionResult, type Adapter, type Capability, type ConversationAction, type ConversationEvent, type DiscoveredRoom, type HeadChange, type MdModelIdentity, type ProviderLimit, type Retention, type RoomAttachment, type RoomVersionNotification, type ServiceMode } from './adapter.js';
2
+ import { type AcceptedMessage, type ActionResult, type Adapter, type Capability, type ConversationAction, type ConversationEvent, type DiscoveredRoom, type HeadChange, type ListedConversation, type ProviderLimit, type Retention, type RoomAttachment, type ServiceMode } from './adapter.js';
3
3
  export type MemoryRoom = DiscoveredRoom & {
4
4
  model?: ModelResult;
5
5
  selectionModel?: ModelResult;
@@ -11,6 +11,7 @@ export type MemoryRoom = DiscoveredRoom & {
11
11
  };
12
12
  export type MemoryConversation = {
13
13
  conversation: string;
14
+ listed?: Omit<ListedConversation, 'conversation'>;
14
15
  messages?: readonly AcceptedMessage[];
15
16
  outcomes?: Partial<Record<ConversationAction, ActionResult>>;
16
17
  };
@@ -19,20 +20,25 @@ export type MemoryAdapterOptions = {
19
20
  conversations?: readonly MemoryConversation[];
20
21
  historyPageSize?: number;
21
22
  pageSize?: number;
22
- mdModel?: MdModelIdentity;
23
- supportedVersions?: readonly number[];
24
23
  capabilities?: readonly Capability[];
25
24
  providerLimits?: readonly ProviderLimit[];
26
25
  retention?: Retention;
26
+ unopened?: boolean;
27
27
  };
28
28
  export type MemoryAdapter = Adapter & {
29
29
  setRooms(rooms: readonly MemoryRoom[]): void;
30
30
  setConversations(conversations: readonly MemoryConversation[]): void;
31
31
  script(operation: keyof Adapter, answer: unknown): void;
32
- notifyRoomVersion(notification: RoomVersionNotification): void;
32
+ open(): void;
33
+ close(revoked?: boolean): void;
34
+ expire(locators: readonly string[]): void;
35
+ notifyRoomVersion(notification: {
36
+ locator: string;
37
+ roomVersion: string;
38
+ }): void;
33
39
  notifyConversation(event: ConversationEvent): void;
34
40
  notifyServiceMode(mode: ServiceMode): void;
35
- selectedRooms(): readonly string[];
41
+ heldRooms(): readonly string[];
36
42
  replicatedConversations(): readonly string[];
37
43
  };
38
44
  export declare function createMemoryAdapter(options?: MemoryAdapterOptions): MemoryAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAEL,KAAK,eAAe,EAEpB,KAAK,YAAY,EACjB,KAAK,OAAO,EAIZ,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EAItB,KAAK,cAAc,EACnB,KAAK,UAAU,EAGf,KAAK,eAAe,EAGpB,KAAK,aAAa,EAGlB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAmBtB,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG;IACxC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,WAAW,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC,CAAC;CAC9D,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9B,aAAa,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,YAAY,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACrC,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,IAAI,CAAC;IAC7C,gBAAgB,CAAC,aAAa,EAAE,SAAS,kBAAkB,EAAE,GAAG,IAAI,CAAC;IACrE,MAAM,CAAC,SAAS,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACxD,iBAAiB,CAAC,YAAY,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC/D,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnD,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3C,aAAa,IAAI,SAAS,MAAM,EAAE,CAAC;IACnC,uBAAuB,IAAI,SAAS,MAAM,EAAE,CAAC;CAC9C,CAAC;AA+BF,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CAiZrF"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,YAAY,EACjB,KAAK,OAAO,EAIZ,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EAItB,KAAK,cAAc,EACnB,KAAK,UAAU,EAGf,KAAK,kBAAkB,EAGvB,KAAK,aAAa,EAGlB,KAAK,SAAS,EACd,KAAK,cAAc,EAGnB,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAkBtB,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG;IACxC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,WAAW,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;IAClD,QAAQ,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC,CAAC;CAC9D,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9B,aAAa,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACrC,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,IAAI,CAAC;IAC7C,gBAAgB,CAAC,aAAa,EAAE,SAAS,kBAAkB,EAAE,GAAG,IAAI,CAAC;IACrE,MAAM,CAAC,SAAS,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACxD,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,MAAM,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAC1C,iBAAiB,CAAC,YAAY,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAChF,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnD,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3C,SAAS,IAAI,SAAS,MAAM,EAAE,CAAC;IAC/B,uBAAuB,IAAI,SAAS,MAAM,EAAE,CAAC;CAC9C,CAAC;AA+CF,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CAwbrF"}
package/dist/memory.js CHANGED
@@ -1,5 +1,3 @@
1
- import { ROOM_CONTRACT_VERSION, } from './adapter.js';
2
- import { MD_MODEL } from './collection.js';
3
1
  import { sameChange } from './overlay.js';
4
2
  const FIXTURE_RETENTION = {
5
3
  history: { kind: 'duration', seconds: 1 },
@@ -15,6 +13,19 @@ function declaredRetention(value) {
15
13
  }
16
14
  throw new Error('history retention duration must be a finite positive number of seconds');
17
15
  }
16
+ const MODEL_ABSENT = { kind: 'model-unavailable', reason: 'not-readable' };
17
+ function modelsOf(room) {
18
+ return {
19
+ collection: room.model ?? MODEL_ABSENT,
20
+ ...(room.typedSelection === undefined
21
+ ? {}
22
+ : { selection: room.selectionModel ?? MODEL_ABSENT }),
23
+ };
24
+ }
25
+ function changedModels(room, from) {
26
+ const now = modelsOf(room);
27
+ return JSON.stringify(now) === JSON.stringify(modelsOf(from)) ? undefined : now;
28
+ }
18
29
  function named(source, paths) {
19
30
  const taken = {};
20
31
  for (const path of paths) {
@@ -31,8 +42,6 @@ async function resolveScript(answer, fallback, request) {
31
42
  }
32
43
  export function createMemoryAdapter(options = {}) {
33
44
  let rooms = options.rooms === undefined ? [] : [...options.rooms];
34
- const mdModel = options.mdModel ?? MD_MODEL;
35
- const supportedVersions = options.supportedVersions ?? [ROOM_CONTRACT_VERSION];
36
45
  const capabilities = options.capabilities ?? [];
37
46
  const providerLimits = options.providerLimits ?? [];
38
47
  const retention = declaredRetention(options.retention);
@@ -47,7 +56,8 @@ export function createMemoryAdapter(options = {}) {
47
56
  const unsealed = new Map();
48
57
  const sealed = new Set();
49
58
  const historyPageSize = options.historyPageSize;
50
- let selected = [];
59
+ let held = [];
60
+ let expiring = [];
51
61
  let replicated = [];
52
62
  let issued = 0;
53
63
  function scriptConversations(entries) {
@@ -89,10 +99,10 @@ export function createMemoryAdapter(options = {}) {
89
99
  return {
90
100
  name: room.name,
91
101
  locator: room.locator,
102
+ handle: room.handle,
92
103
  roomVersion: room.roomVersion,
93
104
  operations: room.operations,
94
105
  replica: room.replica,
95
- attachedModel: room.attachedModel,
96
106
  ...(room.typedSelection === undefined ? {} : { typedSelection: room.typedSelection }),
97
107
  providerOwnedPaths: room.providerOwnedPaths,
98
108
  };
@@ -106,6 +116,7 @@ export function createMemoryAdapter(options = {}) {
106
116
  return {
107
117
  kind: 'bootstrap',
108
118
  roomVersion: room.roomVersion,
119
+ ...(from === 0 ? { models: modelsOf(room) } : {}),
109
120
  documents: named(room.documents ?? {}, taken),
110
121
  revisions: named(room.revisions ?? {}, taken),
111
122
  changes: named(room.changes ?? {}, [...taken, ...targets]),
@@ -136,9 +147,11 @@ export function createMemoryAdapter(options = {}) {
136
147
  : [];
137
148
  const attachments = room.attachments ?? [];
138
149
  const declared = opening && JSON.stringify(attachments) !== JSON.stringify(from.attachments ?? []);
150
+ const models = opening ? changedModels(room, from) : undefined;
139
151
  return {
140
152
  kind: 'net-advancement',
141
153
  roomVersion: room.roomVersion,
154
+ ...(models === undefined ? {} : { models }),
142
155
  documents: named(current, taken),
143
156
  revisions: named(room.revisions ?? {}, taken),
144
157
  changes: named(room.changes ?? {}, [...taken, ...targets]),
@@ -221,11 +234,14 @@ export function createMemoryAdapter(options = {}) {
221
234
  scripted.delete(named);
222
235
  return { kind: 'action', result: { conversation: named } };
223
236
  }
237
+ function announceList() {
238
+ const entries = [...scripted.values()].flatMap(({ conversation, listed }) => listed === undefined ? [] : [{ conversation, ...listed }]);
239
+ for (const listener of listeners)
240
+ listener({ kind: 'list', entries });
241
+ }
224
242
  function discovery() {
225
243
  return {
226
244
  kind: 'discovery',
227
- supportedVersions,
228
- mdModel,
229
245
  rooms: rooms.map(declared),
230
246
  capabilities,
231
247
  providerLimits,
@@ -240,9 +256,21 @@ export function createMemoryAdapter(options = {}) {
240
256
  setConversations(next) {
241
257
  scriptConversations(next);
242
258
  },
243
- notifyRoomVersion(notification) {
259
+ open() {
260
+ announceList();
261
+ for (const observer of observers)
262
+ observer({ kind: 'opened' });
263
+ },
264
+ close(revoked = false) {
265
+ for (const observer of observers)
266
+ observer({ kind: 'closed', revoked });
267
+ },
268
+ expire(locators) {
269
+ expiring = [...locators];
270
+ },
271
+ notifyRoomVersion({ locator, roomVersion }) {
244
272
  for (const observer of observers)
245
- observer(notification);
273
+ observer({ kind: 'room-version', locator, roomVersion });
246
274
  },
247
275
  notifyConversation(event) {
248
276
  if (event.kind === 'accepted-message') {
@@ -256,8 +284,8 @@ export function createMemoryAdapter(options = {}) {
256
284
  for (const observer of modeObservers)
257
285
  observer(mode);
258
286
  },
259
- selectedRooms() {
260
- return selected;
287
+ heldRooms() {
288
+ return held;
261
289
  },
262
290
  replicatedConversations() {
263
291
  return replicated;
@@ -281,12 +309,45 @@ export function createMemoryAdapter(options = {}) {
281
309
  };
282
310
  },
283
311
  },
284
- roomVersions: {
285
- select(locators) {
286
- selected = [...locators];
312
+ roomStream: {
313
+ hold(asked) {
314
+ held = asked.map((room) => room.locator);
315
+ const expired = expiring.filter((locator) => held.includes(locator));
316
+ expiring = [];
317
+ const moved = asked.flatMap((room) => {
318
+ const current = rooms.find((entry) => entry.locator === room.locator);
319
+ return current === undefined ||
320
+ expired.includes(room.locator) ||
321
+ current.roomVersion === room.roomVersion
322
+ ? []
323
+ : [{ locator: room.locator, roomVersion: current.roomVersion }];
324
+ });
325
+ queueMicrotask(() => {
326
+ for (const observer of observers) {
327
+ for (const room of moved)
328
+ observer({ kind: 'room-version', ...room });
329
+ observer({ kind: 'opening', expired });
330
+ }
331
+ });
332
+ },
333
+ reopen() {
334
+ queueMicrotask(() => {
335
+ for (const observer of observers)
336
+ observer({ kind: 'closed', revoked: false });
337
+ });
287
338
  },
288
339
  observe(notify) {
289
340
  observers.add(notify);
341
+ queueMicrotask(() => {
342
+ if (!observers.has(notify))
343
+ return;
344
+ if (options.unopened === true) {
345
+ notify({ kind: 'closed', revoked: false });
346
+ return;
347
+ }
348
+ announceList();
349
+ notify({ kind: 'opened' });
350
+ });
290
351
  return () => {
291
352
  observers.delete(notify);
292
353
  };
@@ -298,13 +359,6 @@ export function createMemoryAdapter(options = {}) {
298
359
  else
299
360
  scripts[operation] = answer;
300
361
  },
301
- async model(_authorization, request) {
302
- return resolveScript(scripts.model, () => {
303
- const room = rooms.find((entry) => entry.locator === request.locator);
304
- const answer = request.attached === 'collection' ? room?.model : room?.selectionModel;
305
- return answer ?? { kind: 'model-unavailable', reason: 'not-readable' };
306
- }, request);
307
- },
308
362
  async authorize() {
309
363
  return resolveScript(scripts.authorize, () => ({}), undefined);
310
364
  },
@@ -317,6 +371,14 @@ export function createMemoryAdapter(options = {}) {
317
371
  });
318
372
  },
319
373
  reached,
374
+ follows(locator, roomVersion, next) {
375
+ const scripted = scripts.follows;
376
+ if (typeof scripted === 'boolean')
377
+ return scripted;
378
+ if (scripted !== undefined)
379
+ return scripted(locator, roomVersion, next);
380
+ return true;
381
+ },
320
382
  async bootstrap(_authorization, request) {
321
383
  return resolveScript(scripts.bootstrap, () => {
322
384
  const room = rooms.find((entry) => entry.locator === request.locator);
@@ -341,10 +403,6 @@ export function createMemoryAdapter(options = {}) {
341
403
  }
342
404
  return advancement(continuation.room, continuation.from, continuation.at);
343
405
  }
344
- if (request.minPosition !== undefined &&
345
- !reached(room.locator, room.roomVersion, request.minPosition)) {
346
- return { kind: 'retryable-refusal', code: 'replica_behind', fields: {} };
347
- }
348
406
  if (request.fromRoomVersion === room.roomVersion) {
349
407
  return { kind: 'still-current' };
350
408
  }
package/dist/model.d.ts CHANGED
@@ -1,31 +1,26 @@
1
- import type { Definition, FieldSpec, SectionSpec, VerifiedModel } from '@agentshouse/mdmodel';
1
+ import type { Definition, ValueFacts, VerifiedModel } from '@agentshouse/mdmodel';
2
2
  export type ModelIdentity = {
3
3
  identity: string;
4
4
  version: string;
5
5
  };
6
6
  export type ModelSnapshot = ModelIdentity & {
7
7
  schema: string | null;
8
+ revision: string | null;
8
9
  };
9
- export type ModelUnavailableReason = 'not-readable' | 'revoked' | 'not-acquired' | 'version-changed' | 'invalid';
10
+ export type ModelUnavailableReason = 'not-readable' | 'revoked' | 'not-acquired' | 'invalid';
10
11
  export type ModelResult = {
11
12
  kind: 'model';
12
13
  snapshot: ModelSnapshot;
13
14
  } | {
14
15
  kind: 'model-unavailable';
15
16
  reason: ModelUnavailableReason;
16
- } | {
17
- kind: 'transport-uncertainty';
18
- } | {
19
- kind: 'revoked-authorization';
20
- };
21
- export type MdType = {
22
- name: string;
23
- fields: Readonly<Record<string, FieldSpec>>;
24
- sections: Readonly<Record<string, SectionSpec>>;
25
17
  };
18
+ export type MdType = Definition;
26
19
  export type ModelState = {
27
20
  status: 'unavailable';
28
21
  reason: ModelUnavailableReason;
22
+ schema?: string | null;
23
+ revision?: string | null;
29
24
  } | {
30
25
  status: 'current' | 'cached';
31
26
  snapshot: ModelSnapshot;
@@ -35,12 +30,16 @@ export type ModelState = {
35
30
  export type TypesResult = {
36
31
  status: 'unavailable';
37
32
  reason: ModelUnavailableReason;
33
+ schema?: string | null;
34
+ revision?: string | null;
38
35
  } | {
39
36
  status: 'current' | 'cached';
40
37
  identity: string;
41
38
  version: string;
42
39
  verifiedWith: ModelIdentity;
43
40
  types: readonly MdType[];
41
+ schema: string | null;
42
+ revision: string | null;
44
43
  };
45
44
  export type ValidationReceipt = {
46
45
  identity: string;
@@ -52,4 +51,5 @@ export declare function definitionOf(state: ModelState, type: string | undefined
52
51
  export declare function modelTypes(state: ModelState): TypesResult;
53
52
  export declare function cached(state: ModelState): ModelState;
54
53
  export declare function sameModel(left: ModelIdentity, right: ModelIdentity): boolean;
54
+ export declare function referenceField(facts: ValueFacts | undefined): boolean;
55
55
  //# sourceMappingURL=model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE9F,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AACtE,MAAM,MAAM,sBAAsB,GAC9B,cAAc,GACd,SAAS,GACT,cAAc,GACd,iBAAiB,GACjB,SAAS,CAAC;AACd,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,uBAAuB,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,uBAAuB,CAAA;CAAE,CAAC;AACtC,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAC5C,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;CACjD,CAAC;AACF,MAAM,MAAM,UAAU,GAClB;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,GACzD;IACE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CAC/B,CAAC;AACN,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,GACzD;IACE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B,CAAC;AACN,MAAM,MAAM,iBAAiB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE,CAAC;AACpG,eAAO,MAAM,QAAQ,EAAE,UAA8D,CAAC;AACtF,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAGhG;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAczD;AACD,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAEpD;AACD,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAE5E"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAElF,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAC/F,MAAM,MAAM,sBAAsB,GAAG,cAAc,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CAAC;AAC7F,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC;AAChC,MAAM,MAAM,UAAU,GAClB;IACE,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GACD;IACE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CAC/B,CAAC;AACN,MAAM,MAAM,WAAW,GACnB;IACE,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GACD;IACE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AACN,MAAM,MAAM,iBAAiB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE,CAAC;AACpG,eAAO,MAAM,QAAQ,EAAE,UAA8D,CAAC;AACtF,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAGhG;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAgBzD;AACD,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAEpD;AACD,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAE5E;AACD,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAErE"}
package/dist/model.js CHANGED
@@ -12,9 +12,9 @@ export function modelTypes(state) {
12
12
  identity: state.snapshot.identity,
13
13
  version: state.snapshot.version,
14
14
  verifiedWith: { ...state.verifiedWith },
15
- types: structuredClone(Object.values(state.types)
16
- .sort((left, right) => (left.name < right.name ? -1 : left.name > right.name ? 1 : 0))
17
- .map(({ name, fields, sections }) => ({ name, fields, sections }))),
15
+ schema: state.snapshot.schema,
16
+ revision: state.snapshot.revision,
17
+ types: structuredClone(Object.values(state.types).sort((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0)),
18
18
  };
19
19
  }
20
20
  export function cached(state) {
@@ -23,3 +23,6 @@ export function cached(state) {
23
23
  export function sameModel(left, right) {
24
24
  return left.identity === right.identity && left.version === right.version;
25
25
  }
26
+ export function referenceField(facts) {
27
+ return facts?.reference !== undefined || facts?.items?.reference !== undefined;
28
+ }
@@ -20,6 +20,8 @@ export type Observed = {
20
20
  end(): void;
21
21
  };
22
22
  export declare function rowsOf(result: QueryResult): readonly (QueryDocument | QueryGroup)[];
23
+ export declare function applied(keyed: KeyedResult, change: QueryChange): KeyedResult;
23
24
  export declare function observed(first: unknown, stop: () => void, keyed: boolean): Observed;
24
25
  export declare function opened(watch: (deliver: (message: unknown) => void) => () => void, keyed: boolean): Promise<Observation<unknown>>;
26
+ export declare function observing<Topic extends string>(watch: (topic: Topic, input: readonly unknown[], deliver: (message: unknown) => void) => () => void): (topic: Topic, ...input: unknown[]) => Promise<Observation<unknown>>;
25
27
  //# sourceMappingURL=observation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzE,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,OAAO,IAAI,CAAC,CAAC;IACb,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACpD,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAErC,MAAM,MAAM,WAAW,GAAG;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAE3E,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC;IACpE,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC,GAAG,IAAI,IAAI,CAAC;CACb,CAAC;AAEF,wBAAgB,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC,aAAa,GAAG,UAAU,CAAC,EAAE,CAEnF;AA0BD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,OAAO,GAAG,QAAQ,CAkCnF;AAED,wBAAgB,MAAM,CACpB,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,KAAK,MAAM,IAAI,EAC1D,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAiB/B"}
1
+ {"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzE,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,OAAO,IAAI,CAAC,CAAC;IACb,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACpD,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAErC,MAAM,MAAM,WAAW,GAAG;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAE3E,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC;IACpE,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC,GAAG,IAAI,IAAI,CAAC;CACb,CAAC;AAEF,wBAAgB,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC,aAAa,GAAG,UAAU,CAAC,EAAE,CAEnF;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,GAAG,WAAW,CAc5E;AAiBD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,OAAO,GAAG,QAAQ,CAkCnF;AAED,wBAAgB,MAAM,CACpB,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,KAAK,MAAM,IAAI,EAC1D,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAiB/B;AAED,wBAAgB,SAAS,CAAC,KAAK,SAAS,MAAM,EAC5C,KAAK,EAAE,CACL,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,SAAS,OAAO,EAAE,EACzB,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,KAChC,MAAM,IAAI,WAEA,KAAK,YAAY,OAAO,EAAE,KAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAQ1E"}
@@ -1,24 +1,29 @@
1
1
  export function rowsOf(result) {
2
2
  return 'groups' in result ? result.groups : result.documents;
3
3
  }
4
+ export function applied(keyed, change) {
5
+ const rows = rowsOf(keyed.result);
6
+ const byKey = new Map(keyed.keys.map((key, index) => [key, rows[index]]));
7
+ for (const key of change.removed)
8
+ byKey.delete(key);
9
+ for (const [key, row] of change.changed)
10
+ byKey.set(key, row);
11
+ const keys = change.order ?? keyed.keys.filter((key) => byKey.has(key));
12
+ const next = keys.map((key) => byKey.get(key));
13
+ return {
14
+ result: 'groups' in keyed.result
15
+ ? { groups: next }
16
+ : { documents: next },
17
+ keys,
18
+ };
19
+ }
4
20
  function keyedResult(first) {
5
- const grouped = 'groups' in first.result;
6
- const rows = rowsOf(first.result);
7
- const byKey = new Map(first.keys.map((key, index) => [key, rows[index]]));
8
- let keys = first.keys;
21
+ let keyed = first;
9
22
  return {
10
23
  value: first.result,
11
24
  next(message) {
12
- const change = message;
13
- for (const key of change.removed)
14
- byKey.delete(key);
15
- for (const [key, row] of change.changed)
16
- byKey.set(key, row);
17
- keys = change.order ?? keys.filter((key) => byKey.has(key));
18
- const next = keys.map((key) => byKey.get(key));
19
- return grouped
20
- ? { groups: next }
21
- : { documents: next };
25
+ keyed = applied(keyed, message);
26
+ return keyed.result;
22
27
  },
23
28
  };
24
29
  }
@@ -83,3 +88,8 @@ export function opened(watch, keyed) {
83
88
  }
84
89
  });
85
90
  }
91
+ export function observing(watch) {
92
+ return (topic, ...input) => opened((deliver) => watch(topic, input, (message) => {
93
+ deliver(structuredClone(message));
94
+ }), topic === 'query');
95
+ }
package/dist/paths.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export declare function normalize(path: string): string | null;
2
- export declare function relative(from: string, target: string): string;
3
2
  export declare function beneath(prefix: string, path: string): boolean;
4
3
  export declare function covered(prefixes: readonly string[], path: string): boolean;
5
4
  //# sourceMappingURL=paths.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAKA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYrD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAK1E"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYrD;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAK1E"}
package/dist/paths.js CHANGED
@@ -1,7 +1,3 @@
1
- function dirname(path) {
2
- const index = path.lastIndexOf('/');
3
- return index === -1 ? '' : path.slice(0, index);
4
- }
5
1
  export function normalize(path) {
6
2
  const parts = [];
7
3
  for (const part of path.split('/')) {
@@ -17,18 +13,6 @@ export function normalize(path) {
17
13
  }
18
14
  return parts.join('/');
19
15
  }
20
- export function relative(from, target) {
21
- const base = dirname(from)
22
- .split('/')
23
- .filter((part) => part !== '');
24
- const parts = target.split('/');
25
- let shared = 0;
26
- while (shared < base.length && shared + 1 < parts.length && base[shared] === parts[shared]) {
27
- shared += 1;
28
- }
29
- const up = Array.from({ length: base.length - shared }, () => '..');
30
- return [...up, ...parts.slice(shared)].join('/');
31
- }
32
16
  export function beneath(prefix, path) {
33
17
  return path === prefix || path.startsWith(`${prefix}/`);
34
18
  }