orez-lite 0.11.1 → 0.11.2

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 (67) hide show
  1. package/dist/cf-do/application-sql.d.ts +10 -3
  2. package/dist/cf-do/application-sql.d.ts.map +1 -1
  3. package/dist/cf-do/application-sql.js.map +1 -1
  4. package/dist/cf-do/lite-data-worker.d.ts.map +1 -1
  5. package/dist/cf-do/lite-data-worker.js +10 -1
  6. package/dist/cf-do/lite-data-worker.js.map +1 -1
  7. package/dist/cf-do/worker.d.ts +1 -1
  8. package/dist/cf-do/worker.d.ts.map +1 -1
  9. package/dist/cf-do/worker.js +3 -0
  10. package/dist/cf-do/worker.js.map +1 -1
  11. package/dist/realtime.d.ts +18 -0
  12. package/dist/realtime.d.ts.map +1 -0
  13. package/dist/realtime.js +18 -0
  14. package/dist/realtime.js.map +1 -0
  15. package/package.json +6 -6
  16. package/dist/realtime/host.d.ts +0 -7
  17. package/dist/realtime/host.d.ts.map +0 -1
  18. package/dist/realtime/host.js +0 -77
  19. package/dist/realtime/host.js.map +0 -1
  20. package/dist/realtime/hub.d.ts +0 -67
  21. package/dist/realtime/hub.d.ts.map +0 -1
  22. package/dist/realtime/hub.js +0 -456
  23. package/dist/realtime/hub.js.map +0 -1
  24. package/dist/realtime/index.d.ts +0 -24
  25. package/dist/realtime/index.d.ts.map +0 -1
  26. package/dist/realtime/index.js +0 -27
  27. package/dist/realtime/index.js.map +0 -1
  28. package/dist/realtime/local.d.ts +0 -15
  29. package/dist/realtime/local.d.ts.map +0 -1
  30. package/dist/realtime/local.js +0 -63
  31. package/dist/realtime/local.js.map +0 -1
  32. package/dist/realtime/manifest.d.ts +0 -51
  33. package/dist/realtime/manifest.d.ts.map +0 -1
  34. package/dist/realtime/manifest.js +0 -110
  35. package/dist/realtime/manifest.js.map +0 -1
  36. package/dist/realtime/message-port.d.ts +0 -34
  37. package/dist/realtime/message-port.d.ts.map +0 -1
  38. package/dist/realtime/message-port.js +0 -141
  39. package/dist/realtime/message-port.js.map +0 -1
  40. package/dist/realtime/producer-socket.d.ts +0 -10
  41. package/dist/realtime/producer-socket.d.ts.map +0 -1
  42. package/dist/realtime/producer-socket.js +0 -90
  43. package/dist/realtime/producer-socket.js.map +0 -1
  44. package/dist/realtime/producer.d.ts +0 -16
  45. package/dist/realtime/producer.d.ts.map +0 -1
  46. package/dist/realtime/producer.js +0 -51
  47. package/dist/realtime/producer.js.map +0 -1
  48. package/dist/realtime/protocol.d.ts +0 -99
  49. package/dist/realtime/protocol.d.ts.map +0 -1
  50. package/dist/realtime/protocol.js +0 -191
  51. package/dist/realtime/protocol.js.map +0 -1
  52. package/dist/realtime/publisher.d.ts +0 -28
  53. package/dist/realtime/publisher.d.ts.map +0 -1
  54. package/dist/realtime/publisher.js +0 -309
  55. package/dist/realtime/publisher.js.map +0 -1
  56. package/dist/realtime/socket-host.d.ts +0 -25
  57. package/dist/realtime/socket-host.d.ts.map +0 -1
  58. package/dist/realtime/socket-host.js +0 -105
  59. package/dist/realtime/socket-host.js.map +0 -1
  60. package/dist/realtime/store.d.ts +0 -28
  61. package/dist/realtime/store.d.ts.map +0 -1
  62. package/dist/realtime/store.js +0 -0
  63. package/dist/realtime/store.js.map +0 -1
  64. package/dist/realtime/writer.d.ts +0 -17
  65. package/dist/realtime/writer.d.ts.map +0 -1
  66. package/dist/realtime/writer.js +0 -138
  67. package/dist/realtime/writer.js.map +0 -1
@@ -1,51 +0,0 @@
1
- import type { RealtimeKeyValue, RealtimeTopic } from './protocol.js';
2
- export type ZeroSchemaShape = {
3
- readonly tables: Readonly<Record<string, {
4
- readonly columns: Readonly<Record<string, {
5
- readonly type: string;
6
- }>>;
7
- readonly primaryKey: readonly string[];
8
- }>>;
9
- };
10
- export type FieldMode = 'append' | 'replace';
11
- export type StreamingFieldOptions = {
12
- readonly maxBytes: number;
13
- readonly maxUpdatesPerSecond: number;
14
- readonly maxBytesPerSecond: number;
15
- readonly mode?: FieldMode;
16
- readonly validate?: (value: unknown) => boolean;
17
- };
18
- export type StreamingFieldSpec = StreamingFieldOptions & {
19
- readonly table: string;
20
- readonly field: string;
21
- readonly mode: FieldMode;
22
- readonly columnType: string;
23
- readonly primaryKey: readonly string[];
24
- };
25
- export type StreamingManifest = {
26
- readonly fields: ReadonlyMap<string, StreamingFieldSpec>;
27
- readonly schemaKey: string;
28
- };
29
- export type StreamingFieldHandle = {
30
- readonly topic: RealtimeTopic;
31
- readonly spec: StreamingFieldSpec;
32
- };
33
- export type StreamingFieldRef<Key, Value> = ((key: Key) => StreamingFieldHandle) & {
34
- readonly spec: StreamingFieldSpec;
35
- readonly __value?: Value;
36
- };
37
- export type StreamingFieldDeclaration = Readonly<Record<string, Readonly<Record<string, StreamingFieldOptions>>>>;
38
- export declare function defineStreamingFields<Declaration extends StreamingFieldDeclaration>(schema: ZeroSchemaShape, declaration: Declaration): {
39
- readonly manifest: StreamingManifest;
40
- } & {
41
- readonly [Table in keyof Declaration]: {
42
- readonly [Field in keyof Declaration[Table]]: StreamingFieldRef<Record<string, RealtimeKeyValue>, unknown>;
43
- };
44
- };
45
- export declare function resolveTopic(manifest: StreamingManifest, topic: RealtimeTopic): {
46
- readonly spec: StreamingFieldSpec;
47
- readonly id: string;
48
- } | {
49
- readonly reason: string;
50
- };
51
- //# sourceMappingURL=manifest.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/realtime/manifest.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAEpE,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CACvB,MAAM,CACJ,MAAM,EACN;QACE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC,CAAA;QACrE,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;KACvC,CACF,CACF,CAAA;CACF,CAAA;AAOD,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAA;AAE5C,MAAM,MAAM,qBAAqB,GAAG;IAElC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IAEzB,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAA;IAGpC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAElC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAA;IAKzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAA;CAChD,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG,qBAAqB,GAAG;IACvD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;CACvC,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;IAIxD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B,CAAA;AAMD,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;IAC7B,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAA;CAClC,CAAA;AAGD,MAAM,MAAM,iBAAiB,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,oBAAoB,CAAC,GAAG;IACjF,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAA;IAEjC,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,CAAA;CACzB,CAAA;AAoBD,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAC9C,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAChE,CAAA;AAED,wBAAgB,qBAAqB,CAAC,WAAW,SAAS,yBAAyB,EACjF,MAAM,EAAE,eAAe,EACvB,WAAW,EAAE,WAAW,GACvB;IACD,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;CACrC,GAAG;IACF,QAAQ,EAAE,KAAK,IAAI,MAAM,WAAW,GAAG;QACrC,QAAQ,EAAE,KAAK,IAAI,MAAM,WAAW,CAAC,KAAK,CAAC,GAAG,iBAAiB,CAC7D,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAChC,OAAO,CACR;KACF;CACF,CA0EA;AAuBD,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,aAAa,GAElB;IAAE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAU9B"}
@@ -1,110 +0,0 @@
1
- // The streaming-field manifest: which columns may stream, in what mode, under
2
- // what bounds.
3
- //
4
- // It stays PARALLEL to the Zero schema rather than being a property on it.
5
- // Zero derives its client schema and compatibility hash from the stock column
6
- // shape, so an orez-specific property there would change Zero's schema identity
7
- // or depend on how its runtime treats unknown keys. The manifest takes the
8
- // schema as input, validates every table and column against it, and produces a
9
- // separate object.
10
- import { canonicalTopic } from './protocol.js';
11
- const APPENDABLE_TYPES = new Set(['string']);
12
- const VALIDATOR_REQUIRED_TYPES = new Set(['json']);
13
- function schemaIdentity(schema, fields) {
14
- // identity covers exactly what a mismatch would break: the streamed columns,
15
- // their type, their mode, and the key ordering topics are built from.
16
- return fields
17
- .map((spec) => {
18
- const table = schema.tables[spec.table];
19
- return `${spec.table}.${spec.field}:${spec.columnType}:${spec.mode}:${table.primaryKey.join(',')}`;
20
- })
21
- .sort()
22
- .join('|');
23
- }
24
- export function defineStreamingFields(schema, declaration) {
25
- const specs = [];
26
- const tables = {};
27
- for (const [table, fields] of Object.entries(declaration)) {
28
- const schemaTable = schema.tables[table];
29
- if (!schemaTable) {
30
- throw new TypeError(`streaming field table '${table}' is not in the Zero schema`);
31
- }
32
- if (schemaTable.primaryKey.length === 0) {
33
- throw new TypeError(`streaming field table '${table}' has no primary key`);
34
- }
35
- const refs = {};
36
- for (const [field, options] of Object.entries(fields)) {
37
- const column = schemaTable.columns[field];
38
- if (!column) {
39
- throw new TypeError(`streaming field '${table}.${field}' is not in the Zero schema`);
40
- }
41
- if (schemaTable.primaryKey.includes(field)) {
42
- throw new TypeError(`streaming field '${table}.${field}' is a primary key column; a streamed key would change the row's identity mid-generation`);
43
- }
44
- validateBounds(table, field, options);
45
- const mode = options.mode ?? (APPENDABLE_TYPES.has(column.type) ? 'append' : 'replace');
46
- if (mode === 'append' && !APPENDABLE_TYPES.has(column.type)) {
47
- throw new TypeError(`streaming field '${table}.${field}' is a ${column.type} column; append mode concatenates and only applies to string columns`);
48
- }
49
- if (VALIDATOR_REQUIRED_TYPES.has(column.type) && !options.validate) {
50
- throw new TypeError(`streaming field '${table}.${field}' is a ${column.type} column and must supply validate(); Zero carries no runtime validator for it and realtime values bypass PayloadCodec.decodePull`);
51
- }
52
- const spec = {
53
- ...options,
54
- table,
55
- field,
56
- mode,
57
- columnType: column.type,
58
- primaryKey: schemaTable.primaryKey,
59
- };
60
- specs.push(spec);
61
- const ref = ((key) => {
62
- for (const column of spec.primaryKey) {
63
- if (key[column] === undefined) {
64
- throw new TypeError(`streaming topic '${table}.${field}' is missing primary key column '${column}'`);
65
- }
66
- }
67
- return { topic: { table, key, field }, spec };
68
- });
69
- Object.defineProperty(ref, 'spec', { value: spec, enumerable: true });
70
- refs[field] = ref;
71
- }
72
- tables[table] = refs;
73
- }
74
- const fieldMap = new Map();
75
- for (const spec of specs)
76
- fieldMap.set(`${spec.table}.${spec.field}`, spec);
77
- return {
78
- ...tables,
79
- manifest: { fields: fieldMap, schemaKey: schemaIdentity(schema, specs) },
80
- };
81
- }
82
- function validateBounds(table, field, options) {
83
- const bounds = [
84
- ['maxBytes', options.maxBytes],
85
- ['maxUpdatesPerSecond', options.maxUpdatesPerSecond],
86
- ['maxBytesPerSecond', options.maxBytesPerSecond],
87
- ];
88
- for (const [name, value] of bounds) {
89
- if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {
90
- throw new TypeError(`streaming field '${table}.${field}' needs a positive ${name}`);
91
- }
92
- }
93
- }
94
- // Host-side lookup: resolve a topic against the manifest, returning the spec
95
- // and the canonical wire identity, or a reason the topic is not streamable.
96
- // Every host runs this before it will fan anything out, so a producer bug or a
97
- // crafted subscribe frame cannot create a topic outside the manifest.
98
- export function resolveTopic(manifest, topic) {
99
- const spec = manifest.fields.get(`${topic.table}.${topic.field}`);
100
- if (!spec)
101
- return { reason: `'${topic.table}.${topic.field}' is not a streaming field` };
102
- for (const column of spec.primaryKey) {
103
- const value = topic.key[column];
104
- if (value === undefined) {
105
- return { reason: `topic is missing primary key column '${column}'` };
106
- }
107
- }
108
- return { spec, id: canonicalTopic(spec.primaryKey, topic) };
109
- }
110
- //# sourceMappingURL=manifest.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/realtime/manifest.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,eAAe;AACf,EAAE;AACF,2EAA2E;AAC3E,8EAA8E;AAC9E,gFAAgF;AAChF,2EAA2E;AAC3E,+EAA+E;AAC/E,mBAAmB;AAEnB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAwE9C,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;AAC5C,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;AAElD,SAAS,cAAc,CACrB,MAAuB,EACvB,MAAqC;IAErC,6EAA6E;IAC7E,sEAAsE;IACtE,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAE,CAAA;QACxC,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;IACpG,CAAC,CAAC;SACD,IAAI,EAAE;SACN,IAAI,CAAC,GAAG,CAAC,CAAA;AACd,CAAC;AAMD,MAAM,UAAU,qBAAqB,CACnC,MAAuB,EACvB,WAAwB;IAWxB,MAAM,KAAK,GAAyB,EAAE,CAAA;IACtC,MAAM,MAAM,GAAsE,EAAE,CAAA;IAEpF,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QAC1D,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACxC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,SAAS,CAAC,0BAA0B,KAAK,6BAA6B,CAAC,CAAA;QACnF,CAAC;QACD,IAAI,WAAW,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,SAAS,CAAC,0BAA0B,KAAK,sBAAsB,CAAC,CAAA;QAC5E,CAAC;QACD,MAAM,IAAI,GAAsD,EAAE,CAAA;QAElE,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACtD,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;YACzC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,SAAS,CACjB,oBAAoB,KAAK,IAAI,KAAK,6BAA6B,CAChE,CAAA;YACH,CAAC;YACD,IAAI,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3C,MAAM,IAAI,SAAS,CACjB,oBAAoB,KAAK,IAAI,KAAK,0FAA0F,CAC7H,CAAA;YACH,CAAC;YACD,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;YAErC,MAAM,IAAI,GACR,OAAO,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;YAC5E,IAAI,IAAI,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5D,MAAM,IAAI,SAAS,CACjB,oBAAoB,KAAK,IAAI,KAAK,UAAU,MAAM,CAAC,IAAI,sEAAsE,CAC9H,CAAA;YACH,CAAC;YACD,IAAI,wBAAwB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACnE,MAAM,IAAI,SAAS,CACjB,oBAAoB,KAAK,IAAI,KAAK,UAAU,MAAM,CAAC,IAAI,iIAAiI,CACzL,CAAA;YACH,CAAC;YAED,MAAM,IAAI,GAAuB;gBAC/B,GAAG,OAAO;gBACV,KAAK;gBACL,KAAK;gBACL,IAAI;gBACJ,UAAU,EAAE,MAAM,CAAC,IAAI;gBACvB,UAAU,EAAE,WAAW,CAAC,UAAU;aACnC,CAAA;YACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAEhB,MAAM,GAAG,GAAG,CAAC,CAAC,GAAqC,EAAwB,EAAE;gBAC3E,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;oBACrC,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC;wBAC9B,MAAM,IAAI,SAAS,CACjB,oBAAoB,KAAK,IAAI,KAAK,oCAAoC,MAAM,GAAG,CAChF,CAAA;oBACH,CAAC;gBACH,CAAC;gBACD,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAA;YAC/C,CAAC,CAAiD,CAAA;YAClD,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAA;YACrE,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAA;QACnB,CAAC;QACD,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;IACtB,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA8B,CAAA;IACtD,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,CAAA;IAE3E,OAAO;QACL,GAAG,MAAM;QACT,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;KAChE,CAAA;AACZ,CAAC;AAED,SAAS,cAAc,CACrB,KAAa,EACb,KAAa,EACb,OAA8B;IAE9B,MAAM,MAAM,GAAG;QACb,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC;QAC9B,CAAC,qBAAqB,EAAE,OAAO,CAAC,mBAAmB,CAAC;QACpD,CAAC,mBAAmB,EAAE,OAAO,CAAC,iBAAiB,CAAC;KACxC,CAAA;IACV,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QACnC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACvE,MAAM,IAAI,SAAS,CAAC,oBAAoB,KAAK,IAAI,KAAK,sBAAsB,IAAI,EAAE,CAAC,CAAA;QACrF,CAAC;IACH,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,4EAA4E;AAC5E,+EAA+E;AAC/E,sEAAsE;AACtE,MAAM,UAAU,YAAY,CAC1B,QAA2B,EAC3B,KAAoB;IAIpB,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;IACjE,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,MAAM,EAAE,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,4BAA4B,EAAE,CAAA;IACxF,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAC/B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,EAAE,MAAM,EAAE,wCAAwC,MAAM,GAAG,EAAE,CAAA;QACtE,CAAC;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,CAAA;AAC7D,CAAC"}
@@ -1,34 +0,0 @@
1
- import { RealtimeHub } from './hub.js';
2
- import { RealtimeStore } from './store.js';
3
- import type { RealtimeIdentity } from './hub.js';
4
- import type { StreamingManifest } from './manifest.js';
5
- import type { RealtimeTopic } from './protocol.js';
6
- import type { RealtimePublisher } from './publisher.js';
7
- import type { FieldWriter } from './writer.js';
8
- export type MembershipReader = (identity: RealtimeIdentity, table: string, key: Readonly<Record<string, boolean | null | number | string>>) => Promise<{
9
- readonly ownsGroup: boolean;
10
- readonly authorized: boolean;
11
- }>;
12
- export type BrowserRealtimeOptions = {
13
- readonly manifest: StreamingManifest;
14
- readonly readMembership: MembershipReader;
15
- readonly onError?: (message: string) => void;
16
- };
17
- export declare class BrowserRealtime {
18
- #private;
19
- constructor(options: BrowserRealtimeOptions);
20
- get fields(): FieldWriter;
21
- get publisher(): RealtimePublisher;
22
- connect(port: MessagePort, identity: RealtimeIdentity): () => void;
23
- revokeMembership(clientGroupID: string, removed: readonly RealtimeTopic[]): void;
24
- flush(): void;
25
- get hub(): RealtimeHub;
26
- }
27
- export declare function connectRealtimePort(port: MessagePort, options?: {
28
- readonly staleAfterMs?: number;
29
- readonly onError?: (message: string) => void;
30
- }): {
31
- readonly store: RealtimeStore;
32
- readonly close: () => void;
33
- };
34
- //# sourceMappingURL=message-port.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"message-port.d.ts","sourceRoot":"","sources":["../../src/realtime/message-port.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAGtC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1C,OAAO,KAAK,EAGV,gBAAgB,EAEjB,MAAM,UAAU,CAAA;AACjB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAEtD,OAAO,KAAK,EAAa,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAI9C,MAAM,MAAM,gBAAgB,GAAG,CAC7B,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC,CAAC,KAC5D,OAAO,CAAC;IAAE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAAA;AAE3E,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;IACpC,QAAQ,CAAC,cAAc,EAAE,gBAAgB,CAAA;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAC7C,CAAA;AAED,qBAAa,eAAe;;gBAMd,OAAO,EAAE,sBAAsB;IAqC3C,IAAI,MAAM,IAAI,WAAW,CAExB;IAID,IAAI,SAAS,IAAI,iBAAiB,CAEjC;IAKD,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,gBAAgB,GAAG,MAAM,IAAI;IAqClE,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI;IAIhF,KAAK,IAAI,IAAI;IAIb,IAAI,GAAG,IAAI,WAAW,CAErB;CACF;AAKD,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,WAAW,EACjB,OAAO,GAAE;IACP,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACxC,GACL;IAAE,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAA;CAAE,CAiC/D"}
@@ -1,141 +0,0 @@
1
- // MessagePort realtime adapter: the browser-worker host's transport.
2
- //
3
- // The hub state machine, publisher, and protocol are shared with every other
4
- // host (orez-lite/realtime). This file is only the browser's socket lifecycle:
5
- // a MessagePort instead of a WebSocket, and an authorizer that reads the same
6
- // durable query membership the pull path maintains.
7
- //
8
- // The worker and its producer share one process lifecycle, so subscriptions and
9
- // stream generations are memory-only here. Nothing survives a worker restart,
10
- // which is correct: the durable value is whatever the client's next Zero pull
11
- // produces.
12
- import { applyClientFrame, applyHostFrame } from './host.js';
13
- import { RealtimeHub } from './hub.js';
14
- import { createProducer, inProcessTransport } from './producer.js';
15
- import { decodeFrame, encodeFrame } from './protocol.js';
16
- import { RealtimeStore } from './store.js';
17
- export class BrowserRealtime {
18
- #hub;
19
- #producer;
20
- #producerCounter = 0;
21
- #connectionCounter = 0;
22
- constructor(options) {
23
- this.#hub = new RealtimeHub({
24
- manifest: options.manifest,
25
- authorizeSubscribe: async (identity, topic) => {
26
- const { ownsGroup, authorized } = await options.readMembership(identity, topic.table, topic.key);
27
- // A client group id is not a bearer token: not owning it is a denial,
28
- // and the reason deliberately does not say whether the row exists.
29
- if (!ownsGroup) {
30
- return { status: 'denied', reason: 'client group does not belong to this user' };
31
- }
32
- // Owning the group without membership is the optimistic-row race: the
33
- // client holds a row from its own mutation that the server has not
34
- // recorded yet. It retries after its next pull.
35
- return authorized ? { status: 'active' } : { status: 'pending' };
36
- },
37
- });
38
- // There is no producer socket in the browser: the code running the model
39
- // loop and the hub share one JavaScript context, so begin/publish are
40
- // direct calls. The producer ROLE is still the shared one, so a loop
41
- // written here runs unchanged against a socket host.
42
- const producerHandle = {
43
- id: `browser-producer-${++this.#producerCounter}`,
44
- send: () => { },
45
- };
46
- this.#producer = createProducer(inProcessTransport(this.#hub, producerHandle), options);
47
- }
48
- // Imperative writing: set a row's field to its current value, generations
49
- // managed for you. Trusted by construction, this is the worker's own code.
50
- get fields() {
51
- return this.#producer.fields;
52
- }
53
- // The explicit generation API underneath, for a producer that controls begin,
54
- // commit, and end itself.
55
- get publisher() {
56
- return this.#producer.publisher;
57
- }
58
- // Attach a port. The identity comes from the host's authenticated pull path,
59
- // never from the port itself, so a page cannot claim another user's client
60
- // group by asserting one over the channel.
61
- connect(port, identity) {
62
- const connection = {
63
- id: `browser-connection-${++this.#connectionCounter}`,
64
- identity,
65
- send: (frame) => {
66
- port.postMessage({ event: 'realtime', frame: encodeFrame(frame) });
67
- },
68
- };
69
- const onMessage = (event) => {
70
- const message = event.data;
71
- if (!message ||
72
- typeof message !== 'object' ||
73
- message.event !== 'realtime') {
74
- return;
75
- }
76
- const raw = message.frame;
77
- if (typeof raw !== 'string')
78
- return;
79
- const frame = decodeFrame(raw);
80
- if (!frame)
81
- return;
82
- // A subscriber channel is never a publish channel. Only subscribe and
83
- // unsubscribe are accepted here, whatever else a port sends.
84
- if (frame[0] !== 'subscribe' && frame[0] !== 'unsubscribe')
85
- return;
86
- void applyClientFrame(this.#hub, connection, frame);
87
- };
88
- port.addEventListener('message', onMessage);
89
- return () => {
90
- port.removeEventListener('message', onMessage);
91
- this.#hub.dropConnection(connection.id);
92
- };
93
- }
94
- // A pull removed rows from a client group's membership, so its field
95
- // subscriptions for those rows go with them.
96
- revokeMembership(clientGroupID, removed) {
97
- this.#hub.revokeMembership(clientGroupID, removed);
98
- }
99
- flush() {
100
- this.#hub.flush();
101
- }
102
- get hub() {
103
- return this.#hub;
104
- }
105
- }
106
- // The page-side half of the port transport. Owns a RealtimeStore and pumps
107
- // frames both ways, so `useStreamingField` sees the same store it would against
108
- // a WebSocket host.
109
- export function connectRealtimePort(port, options = {}) {
110
- const store = new RealtimeStore({
111
- send: (frame) => {
112
- port.postMessage({ event: 'realtime', frame: encodeFrame(frame) });
113
- },
114
- staleAfterMs: options.staleAfterMs,
115
- onError: options.onError,
116
- });
117
- const onMessage = (event) => {
118
- const message = event.data;
119
- if (!message ||
120
- typeof message !== 'object' ||
121
- message.event !== 'realtime') {
122
- return;
123
- }
124
- const raw = message.frame;
125
- if (typeof raw !== 'string')
126
- return;
127
- const frame = decodeFrame(raw);
128
- if (frame)
129
- applyHostFrame(store, frame);
130
- };
131
- port.addEventListener('message', onMessage);
132
- port.start();
133
- return {
134
- store,
135
- close: () => {
136
- port.removeEventListener('message', onMessage);
137
- store.handleDisconnect();
138
- },
139
- };
140
- }
141
- //# sourceMappingURL=message-port.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"message-port.js","sourceRoot":"","sources":["../../src/realtime/message-port.ts"],"names":[],"mappings":"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"}
@@ -1,10 +0,0 @@
1
- import type { ProducerOptions, RealtimeProducer } from './producer.js';
2
- export type ProducerSocket = {
3
- send(data: string): void;
4
- };
5
- export type SocketProducer = RealtimeProducer & {
6
- handleMessage(raw: string): void;
7
- fail(reason: string): void;
8
- };
9
- export declare function createSocketProducer(socket: ProducerSocket, options: ProducerOptions): SocketProducer;
10
- //# sourceMappingURL=producer-socket.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"producer-socket.d.ts","sourceRoot":"","sources":["../../src/realtime/producer-socket.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAItE,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG;IAE9C,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAIhC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B,CAAA;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,eAAe,GACvB,cAAc,CA2EhB"}
@@ -1,90 +0,0 @@
1
- // A PublisherTransport backed by a socket, for a producer that is not in the
2
- // same process as the hub.
3
- //
4
- // This is the shape soot does NOT need and the shape agentbus and chat do: an
5
- // application server generates the values, and the subscribers are browsers
6
- // somewhere else, so the updates have to cross a network to reach the hub that
7
- // fans them out.
8
- //
9
- // One socket carries every generation the producer has open. A server writing
10
- // twenty agent sessions holds one connection, and the hub releases all twenty
11
- // leases when it drops.
12
- //
13
- // Connecting, authenticating, and reconnecting are the caller's: it knows its
14
- // own deployment. This owns only the frame bookkeeping on top of a socket that
15
- // is already open.
16
- import { createProducer } from './producer.js';
17
- import { decodeFrame, encodeFrame } from './protocol.js';
18
- export function createSocketProducer(socket, options) {
19
- const pendingBegins = new Map();
20
- // streamID -> why it is unusable. Set by a host rejection or supersession, and
21
- // raised on the producer's next publish for that stream.
22
- const failures = new Map();
23
- // The socket itself died. This is deliberately not per-stream: once the
24
- // connection is gone every generation on it is gone, including ones that
25
- // began successfully and are therefore absent from `failures`.
26
- let socketFailure;
27
- const transport = {
28
- begin(topic, streamID) {
29
- if (socketFailure)
30
- return Promise.reject(new Error(socketFailure));
31
- return new Promise((resolve, reject) => {
32
- pendingBegins.set(streamID, { resolve, reject });
33
- socket.send(encodeFrame(['begin', { topic, streamID }]));
34
- });
35
- },
36
- publish(update) {
37
- if (socketFailure)
38
- throw new Error(socketFailure);
39
- const failure = failures.get(update.streamID);
40
- if (failure)
41
- throw new Error(failure);
42
- socket.send(encodeFrame(['publish', { update }]));
43
- },
44
- end(streamID) {
45
- failures.delete(streamID);
46
- pendingBegins.delete(streamID);
47
- },
48
- };
49
- return {
50
- ...createProducer(transport, options),
51
- handleMessage(raw) {
52
- const frame = decodeFrame(raw);
53
- if (!frame)
54
- return;
55
- switch (frame[0]) {
56
- case 'begin-result': {
57
- const { streamID, reason } = frame[1];
58
- const pending = pendingBegins.get(streamID);
59
- if (!pending)
60
- return;
61
- pendingBegins.delete(streamID);
62
- if (reason === null)
63
- pending.resolve();
64
- else
65
- pending.reject(new Error(reason));
66
- return;
67
- }
68
- case 'publish-rejected': {
69
- const { streamID, reason } = frame[1];
70
- failures.set(streamID, reason);
71
- return;
72
- }
73
- case 'superseded': {
74
- const { topic, streamID } = frame[1];
75
- failures.set(streamID, `generation for '${topic}' was superseded by a newer one`);
76
- return;
77
- }
78
- default:
79
- return;
80
- }
81
- },
82
- fail(reason) {
83
- socketFailure = reason;
84
- for (const pending of pendingBegins.values())
85
- pending.reject(new Error(reason));
86
- pendingBegins.clear();
87
- },
88
- };
89
- }
90
- //# sourceMappingURL=producer-socket.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"producer-socket.js","sourceRoot":"","sources":["../../src/realtime/producer-socket.ts"],"names":[],"mappings":"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"}
@@ -1,16 +0,0 @@
1
- import { RealtimePublisher } from './publisher.js';
2
- import { FieldWriter } from './writer.js';
3
- import type { RealtimeHub, HubProducer } from './hub.js';
4
- import type { StreamingManifest } from './manifest.js';
5
- import type { PublisherTransport } from './publisher.js';
6
- export type RealtimeProducer = {
7
- readonly fields: FieldWriter;
8
- readonly publisher: RealtimePublisher;
9
- };
10
- export type ProducerOptions = {
11
- readonly manifest: StreamingManifest;
12
- readonly onError?: (message: string) => void;
13
- };
14
- export declare function createProducer(transport: PublisherTransport, options: ProducerOptions): RealtimeProducer;
15
- export declare function inProcessTransport(hub: RealtimeHub, producer: HubProducer): PublisherTransport;
16
- //# sourceMappingURL=producer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"producer.d.ts","sourceRoot":"","sources":["../../src/realtime/producer.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAEtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAExD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAA;CACtC,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;IAIpC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAC7C,CAAA;AAED,wBAAgB,cAAc,CAC5B,SAAS,EAAE,kBAAkB,EAC7B,OAAO,EAAE,eAAe,GACvB,gBAAgB,CAQlB;AASD,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,WAAW,GACpB,kBAAkB,CAcpB"}
@@ -1,51 +0,0 @@
1
- // The producer role, identical on every surface.
2
- //
3
- // A producer is whatever generates values: a browser agent loop, an application
4
- // server, a Rust daemon. What differs between them is only how their frames
5
- // reach the hub (a direct call, a MessagePort, a WebSocket). What must NOT
6
- // differ is the API they write through, because otherwise moving a producer
7
- // between surfaces means rewriting it.
8
- //
9
- // So the transport varies and this does not. Every surface builds its producer
10
- // here, and every producer gets the same two handles:
11
- //
12
- // fields imperative: set(handle, value), generations managed for you.
13
- // This is what a token loop wants and what most code should use.
14
- // publisher the explicit generation API underneath, for a producer that
15
- // needs to control begin, commit, and end itself.
16
- import { RealtimePublisher } from './publisher.js';
17
- import { FieldWriter } from './writer.js';
18
- export function createProducer(transport, options) {
19
- const publisher = new RealtimePublisher(transport, options.manifest);
20
- const fields = new FieldWriter(publisher, {
21
- onError: (error, topic) => {
22
- options.onError?.(`${topic.table}.${topic.field}: ${error.message}`);
23
- },
24
- });
25
- return { fields, publisher };
26
- }
27
- // The transport for a producer that shares a process with the hub: the local
28
- // single-client host and the browser worker. `begin` and `publish` are direct
29
- // calls, so there is nothing to serialize and nothing to await.
30
- //
31
- // A rejection throws, which is what the publisher's own failure handling
32
- // expects; it converts that into a reported error rather than letting it reach
33
- // the producer's loop.
34
- export function inProcessTransport(hub, producer) {
35
- return {
36
- begin: (topic, streamID) => {
37
- const result = hub.beginGeneration(producer, topic, streamID);
38
- if (!result.ok)
39
- throw new Error(result.reason);
40
- },
41
- publish: (update) => {
42
- const result = hub.publish(producer, update);
43
- if (!result.ok)
44
- throw new Error(result.reason);
45
- },
46
- // Nothing to release: the generation closed when its terminal update was
47
- // published, and there is no socket whose bookkeeping could outlive it.
48
- end: () => { },
49
- };
50
- }
51
- //# sourceMappingURL=producer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"producer.js","sourceRoot":"","sources":["../../src/realtime/producer.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,EAAE;AACF,gFAAgF;AAChF,4EAA4E;AAC5E,2EAA2E;AAC3E,4EAA4E;AAC5E,uCAAuC;AACvC,EAAE;AACF,+EAA+E;AAC/E,sDAAsD;AACtD,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,2EAA2E;AAC3E,+DAA+D;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAoBzC,MAAM,UAAU,cAAc,CAC5B,SAA6B,EAC7B,OAAwB;IAExB,MAAM,SAAS,GAAG,IAAI,iBAAiB,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IACpE,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,SAAS,EAAE;QACxC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACxB,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QACtE,CAAC;KACF,CAAC,CAAA;IACF,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;AAC9B,CAAC;AAED,6EAA6E;AAC7E,8EAA8E;AAC9E,gEAAgE;AAChE,EAAE;AACF,yEAAyE;AACzE,+EAA+E;AAC/E,uBAAuB;AACvB,MAAM,UAAU,kBAAkB,CAChC,GAAgB,EAChB,QAAqB;IAErB,OAAO;QACL,KAAK,EAAE,CAAC,KAAoB,EAAE,QAAgB,EAAE,EAAE;YAChD,MAAM,MAAM,GAAG,GAAG,CAAC,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAA;YAC7D,IAAI,CAAC,MAAM,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAChD,CAAC;QACD,OAAO,EAAE,CAAC,MAAmB,EAAE,EAAE;YAC/B,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;YAC5C,IAAI,CAAC,MAAM,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAChD,CAAC;QACD,yEAAyE;QACzE,wEAAwE;QACxE,GAAG,EAAE,GAAG,EAAE,GAAE,CAAC;KACd,CAAA;AACH,CAAC"}