@peers-app/peers-sdk 0.26.6 → 0.27.0

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 (182) hide show
  1. package/README.md +3 -1
  2. package/bin/peers-package.js +13 -0
  3. package/define/package.json +4 -0
  4. package/dist/contracts/__tests__/action-dispatch.test.js +56 -76
  5. package/dist/contracts/__tests__/also-implements.test.d.ts +1 -0
  6. package/dist/contracts/__tests__/also-implements.test.js +110 -0
  7. package/dist/contracts/__tests__/builder.test.js +45 -0
  8. package/dist/contracts/__tests__/contract-resolvers.test.js +134 -4
  9. package/dist/contracts/__tests__/frozen-contracts.test.d.ts +1 -0
  10. package/dist/contracts/__tests__/frozen-contracts.test.js +191 -0
  11. package/dist/contracts/__tests__/generic-tool-dispatch.test.js +13 -56
  12. package/dist/contracts/__tests__/host-contract-client.test.d.ts +1 -0
  13. package/dist/contracts/__tests__/host-contract-client.test.js +793 -0
  14. package/dist/contracts/__tests__/host-contract-transport.test.js +15 -0
  15. package/dist/contracts/__tests__/registry.test.js +68 -0
  16. package/dist/contracts/__tests__/target-dispatch.d.ts +11 -0
  17. package/dist/contracts/__tests__/target-dispatch.js +24 -0
  18. package/dist/contracts/__tests__/tool-catalog-service.test.js +37 -1
  19. package/dist/contracts/__tests__/tool-catalog.test.js +12 -3
  20. package/dist/contracts/__tests__/validate.test.js +177 -7
  21. package/dist/contracts/__tests__/workflow-context.test.js +0 -11
  22. package/dist/contracts/builder.d.ts +16 -2
  23. package/dist/contracts/builder.js +44 -3
  24. package/dist/contracts/contract-definition-schema.d.ts +251 -0
  25. package/dist/contracts/contract-definition-schema.js +48 -0
  26. package/dist/contracts/contract-provider-router.d.ts +2 -0
  27. package/dist/contracts/contract-provider-router.js +5 -2
  28. package/dist/contracts/contract-proxy.d.ts +52 -18
  29. package/dist/contracts/contract-proxy.js +144 -203
  30. package/dist/contracts/contract-resolvers.d.ts +6 -4
  31. package/dist/contracts/contract-resolvers.js +32 -9
  32. package/dist/contracts/frozen-contracts.d.ts +59 -0
  33. package/dist/contracts/frozen-contracts.js +86 -0
  34. package/dist/contracts/host-contract-client.d.ts +134 -0
  35. package/dist/contracts/host-contract-client.js +396 -0
  36. package/dist/contracts/host-contract-transport.d.ts +2 -0
  37. package/dist/contracts/host-contract-transport.js +8 -0
  38. package/dist/contracts/index.d.ts +6 -4
  39. package/dist/contracts/index.js +11 -5
  40. package/dist/contracts/registry.d.ts +31 -1
  41. package/dist/contracts/registry.js +100 -6
  42. package/dist/contracts/system/contract-catalog-contract.d.ts +61 -6
  43. package/dist/contracts/system/contract-catalog-contract.js +17 -5
  44. package/dist/contracts/tool-catalog-service.js +26 -6
  45. package/dist/contracts/tool-catalog.d.ts +1 -1
  46. package/dist/contracts/tool-catalog.js +4 -1
  47. package/dist/contracts/types.d.ts +32 -2
  48. package/dist/contracts/validate.d.ts +16 -1
  49. package/dist/contracts/validate.js +139 -25
  50. package/dist/data/change-tracking.d.ts +17 -5
  51. package/dist/data/change-tracking.js +22 -6
  52. package/dist/data/change-tracking.test.d.ts +1 -0
  53. package/dist/data/change-tracking.test.js +62 -0
  54. package/dist/data/orm/sql.data-source.d.ts +9 -0
  55. package/dist/data/orm/sql.data-source.js +47 -2
  56. package/dist/data/orm/sql.data-source.test.js +142 -0
  57. package/dist/data/orm/table-container.js +9 -9
  58. package/dist/data/orm/table-container.test.js +44 -0
  59. package/dist/data/orm/types.d.ts +41 -1
  60. package/dist/data/orm/types.js +159 -28
  61. package/dist/data/orm/types.test.js +129 -0
  62. package/dist/data/peer-types.d.ts +8 -62
  63. package/dist/data/persistent-vars.d.ts +4 -1
  64. package/dist/data/persistent-vars.js +7 -2
  65. package/dist/data/tools.d.ts +29 -221
  66. package/dist/define/also-implements.test.d.ts +1 -0
  67. package/dist/define/also-implements.test.js +123 -0
  68. package/dist/define/context.d.ts +77 -0
  69. package/dist/define/context.js +2 -0
  70. package/dist/define/contract-ref.d.ts +177 -0
  71. package/dist/define/contract-ref.js +67 -0
  72. package/dist/define/declare-contract.d.ts +167 -0
  73. package/dist/define/declare-contract.js +220 -0
  74. package/dist/define/declare-contract.test.d.ts +1 -0
  75. package/dist/define/declare-contract.test.js +573 -0
  76. package/dist/define/define-package.d.ts +203 -0
  77. package/dist/define/define-package.js +289 -0
  78. package/dist/define/define.test.d.ts +1 -0
  79. package/dist/define/define.test.js +1010 -0
  80. package/dist/define/empty-fields.d.ts +15 -0
  81. package/dist/define/empty-fields.js +134 -0
  82. package/dist/define/empty-fields.test.d.ts +1 -0
  83. package/dist/define/empty-fields.test.js +55 -0
  84. package/dist/define/events-observables.test.d.ts +1 -0
  85. package/dist/define/events-observables.test.js +1013 -0
  86. package/dist/define/events.d.ts +81 -0
  87. package/dist/define/events.js +81 -0
  88. package/dist/define/generated-field.d.ts +20 -0
  89. package/dist/define/generated-field.js +25 -0
  90. package/dist/define/index.d.ts +28 -0
  91. package/dist/define/index.js +62 -0
  92. package/dist/define/lazy-members.d.ts +8 -0
  93. package/dist/define/lazy-members.js +38 -0
  94. package/dist/define/manifest.d.ts +63 -0
  95. package/dist/define/manifest.js +653 -0
  96. package/dist/define/observables.d.ts +146 -0
  97. package/dist/define/observables.js +187 -0
  98. package/dist/define/serve-members.d.ts +21 -0
  99. package/dist/define/serve-members.js +152 -0
  100. package/dist/define/serve-members.test.d.ts +1 -0
  101. package/dist/define/serve-members.test.js +630 -0
  102. package/dist/define/serve.d.ts +22 -0
  103. package/dist/define/serve.js +58 -0
  104. package/dist/define/system-contracts.d.ts +41 -0
  105. package/dist/define/system-contracts.js +21 -0
  106. package/dist/define/table-handle.d.ts +13 -0
  107. package/dist/define/table-handle.js +36 -0
  108. package/dist/define/table.d.ts +128 -0
  109. package/dist/define/table.js +122 -0
  110. package/dist/define/tool.d.ts +129 -0
  111. package/dist/define/tool.js +91 -0
  112. package/dist/define/vars.d.ts +82 -0
  113. package/dist/define/vars.js +256 -0
  114. package/dist/define/vars.test.d.ts +1 -0
  115. package/dist/define/vars.test.js +39 -0
  116. package/dist/define/wire-value.d.ts +12 -0
  117. package/dist/define/wire-value.js +76 -0
  118. package/dist/define/worker-state.d.ts +15 -0
  119. package/dist/define/worker-state.js +45 -0
  120. package/dist/device/tx-encoding.test.js +10 -0
  121. package/dist/index.d.ts +3 -0
  122. package/dist/index.js +5 -1
  123. package/dist/observable.d.ts +42 -2
  124. package/dist/observable.js +25 -7
  125. package/dist/package-build/build-package.d.ts +60 -0
  126. package/dist/package-build/build-package.js +312 -0
  127. package/dist/package-build/build-package.test.d.ts +1 -0
  128. package/dist/package-build/build-package.test.js +204 -0
  129. package/dist/package-build/cli.d.ts +7 -0
  130. package/dist/package-build/cli.js +218 -0
  131. package/dist/package-build/contract-add.d.ts +35 -0
  132. package/dist/package-build/contract-add.js +97 -0
  133. package/dist/package-build/contract-add.test.d.ts +1 -0
  134. package/dist/package-build/contract-add.test.js +467 -0
  135. package/dist/package-build/contract-source.d.ts +59 -0
  136. package/dist/package-build/contract-source.js +471 -0
  137. package/dist/package-build/freeze-contracts.d.ts +56 -0
  138. package/dist/package-build/freeze-contracts.js +198 -0
  139. package/dist/package-build/freeze-contracts.test.d.ts +1 -0
  140. package/dist/package-build/freeze-contracts.test.js +355 -0
  141. package/dist/package-installer/package-creator.d.ts +4 -0
  142. package/dist/package-installer/package-creator.js +57 -16
  143. package/dist/package-installer/package-creator.test.js +86 -0
  144. package/dist/package-loader/contract-members.d.ts +53 -0
  145. package/dist/package-loader/contract-members.js +31 -0
  146. package/dist/package-loader/contract-package-loader.js +5 -1
  147. package/dist/package-loader/contract-package-loader.test.js +11 -0
  148. package/dist/package-loader/host-authority-loading.test.js +9 -5
  149. package/dist/package-loader/index.d.ts +1 -0
  150. package/dist/package-loader/index.js +1 -0
  151. package/dist/package-loader/isolated-artifact.d.ts +80 -17
  152. package/dist/package-loader/isolated-artifact.js +257 -51
  153. package/dist/package-loader/isolated-artifact.test.js +294 -21
  154. package/dist/package-loader/isolated-runtime.d.ts +22 -7
  155. package/dist/package-loader/isolated-table-gateway.js +30 -11
  156. package/dist/package-loader/isolated-table-gateway.test.js +243 -0
  157. package/dist/package-loader/package-loader.d.ts +8 -1
  158. package/dist/package-loader/package-loader.js +39 -20
  159. package/dist/package-loader/package-loader.test.js +47 -0
  160. package/dist/peer-id.d.ts +25 -0
  161. package/dist/peer-id.js +99 -0
  162. package/dist/serial-json.compat.test.d.ts +1 -0
  163. package/dist/serial-json.compat.test.js +369 -0
  164. package/dist/serial-json.d.ts +41 -5
  165. package/dist/serial-json.js +216 -157
  166. package/dist/serial-json.oracle.d.ts +21 -0
  167. package/dist/serial-json.oracle.js +222 -0
  168. package/dist/serial-json.test.js +315 -0
  169. package/dist/testing/index.d.ts +4 -0
  170. package/dist/testing/index.js +8 -0
  171. package/dist/testing/mock-host-contract.d.ts +123 -0
  172. package/dist/testing/mock-host-contract.js +434 -0
  173. package/dist/testing/mock-host-contract.test.d.ts +1 -0
  174. package/dist/testing/mock-host-contract.test.js +782 -0
  175. package/dist/types/field-type.d.ts +35 -18
  176. package/dist/types/field-type.js +4 -1
  177. package/dist/types/zod-types.d.ts +9 -0
  178. package/dist/types/zod-types.js +8 -2
  179. package/dist/utils.d.ts +1 -25
  180. package/dist/utils.js +10 -90
  181. package/package.json +9 -2
  182. package/testing/package.json +4 -0
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.declareContract = declareContract;
4
+ exports.implementContract = implementContract;
5
+ exports.isContractDeclaration = isContractDeclaration;
6
+ const peer_id_1 = require("../peer-id");
7
+ const contract_ref_1 = require("./contract-ref");
8
+ const define_package_1 = require("./define-package");
9
+ const observables_1 = require("./observables");
10
+ const tool_1 = require("./tool");
11
+ /**
12
+ * Declare a contract's shape without providing it: its id, version, name, and the tables,
13
+ * tools, observables, and events it exposes, with no handlers. Use it for a contract several
14
+ * packages implement (Voice Skill, which every skill provides). Each provider implements it
15
+ * with {@link implementContract}; consumers use the declaration itself as the reference.
16
+ *
17
+ * Tools come from `declareTool` and observables from `declareObservable`: `defineTool` and
18
+ * `defineObservable` without the handler or source. Events (`defineEvent`) and tables
19
+ * (`defineTable`) are listed as they are; a table can't have a `tableClass` here.
20
+ *
21
+ * @param definition - Id, version, name, description, and members.
22
+ */
23
+ function declareContract(definition) {
24
+ const { contractId, version, name } = definition ?? {};
25
+ const label = `Contract ${name} (${contractId}@${version})`;
26
+ const members = (list, what) => {
27
+ if (list === undefined) {
28
+ return [];
29
+ }
30
+ if (!Array.isArray(list)) {
31
+ throw new Error(`${label} ${what} must be an array`);
32
+ }
33
+ return list;
34
+ };
35
+ for (const tool of members(definition?.tools, "tools")) {
36
+ if (tool?.kind !== "tool") {
37
+ throw new Error(`${label} lists something that isn't a tool from declareTool`);
38
+ }
39
+ if ((0, tool_1.isImplementedTool)(tool)) {
40
+ throw new Error(`${label} tool "${tool.definition.name}" has a handler; a declaration lists tools from declareTool`);
41
+ }
42
+ }
43
+ for (const observable of members(definition?.observables, "observables")) {
44
+ if (!(0, observables_1.isPackageObservable)(observable)) {
45
+ throw new Error(`${label} lists an observable that isn't from declareObservable`);
46
+ }
47
+ if ((0, observables_1.isImplementedObservable)(observable)) {
48
+ throw new Error(`${label} observable "${observable.definition.name}" has a source; a declaration lists observables from declareObservable`);
49
+ }
50
+ }
51
+ for (const table of members(definition?.tables, "tables")) {
52
+ if (table?.kind === "table" && table.definition.tableClass !== undefined) {
53
+ throw new Error(`${label} table "${table.definition.name}" has a tableClass; a declaration's tables have none`);
54
+ }
55
+ }
56
+ // The same checks as a provided contract: id, version, names, and member kinds. Handlers and
57
+ // sources are checked above; a placeholder stands in for each so the checks can run.
58
+ checkMembers(definition);
59
+ const declaration = Object.freeze({
60
+ kind: "contract-declaration",
61
+ contractId,
62
+ version,
63
+ name,
64
+ ...(definition.description === undefined ? {} : { description: definition.description }),
65
+ tables: Object.freeze([...members(definition.tables, "tables")]),
66
+ tools: Object.freeze([...members(definition.tools, "tools")]),
67
+ observables: Object.freeze([...members(definition.observables, "observables")]),
68
+ events: Object.freeze([...members(definition.events, "events")]),
69
+ });
70
+ return (0, contract_ref_1.createContractRef)(contractId, version, { declaration });
71
+ }
72
+ /** Run {@link defineContract}'s checks on a declaration, with stand-in handlers and sources. */
73
+ function checkMembers(definition) {
74
+ const handler = () => undefined;
75
+ const source = Object.assign(() => undefined, { subscribe: () => ({ dispose() { } }) });
76
+ (0, define_package_1.defineContract)({
77
+ contractId: definition.contractId,
78
+ version: definition.version,
79
+ name: definition.name,
80
+ description: definition.description,
81
+ tables: definition.tables,
82
+ tools: (definition.tools ?? []).map((tool) => Object.freeze({ ...tool, definition: { ...tool.definition, handler } })),
83
+ observables: (definition.observables ?? []).map((observable) => Object.freeze({ ...observable, definition: { ...observable.definition, source } })),
84
+ events: definition.events,
85
+ });
86
+ }
87
+ /**
88
+ * Implement a declared contract: a handler for each of its tools and a source for each of its
89
+ * observables, by name. Returns the contract for `pkg.provides`, as {@link defineContract}
90
+ * would; its manifest shape comes from the declaration, so it can't drift from it.
91
+ *
92
+ * ```ts
93
+ * export const TimersVoiceSkill = implementContract(VoiceSkill, {
94
+ * tools: { invoke: async ({ tool, args }, ctx) => ({ speech: "Done." }) },
95
+ * observables: { skill: deviceVar<VoiceSkillCatalog>("skill", { defaultValue: catalog }) },
96
+ * });
97
+ * pkg.provides(TimersVoiceSkill);
98
+ * ```
99
+ *
100
+ * A tool's entry may also set this provider's deadline: `{ handler, timeoutMs }`. The
101
+ * declaration's events are emitted with their own `emit`.
102
+ *
103
+ * For a hub's contract, `exposes` lists other contracts the package provides whose tools the
104
+ * hub contract's consumers may call on this provider: `exposes: [News]`. Each must also be in
105
+ * `pkg.provides`. The hub reaches only their tools, each at its own access level, as the user.
106
+ *
107
+ * @param declaration - From {@link declareContract}.
108
+ * @param implementation - Handlers and sources, by member name, and the contracts it exposes.
109
+ */
110
+ function implementContract(declaration, implementation) {
111
+ const members = declaration
112
+ ?.declaration;
113
+ if (declaration?.kind !== "contract-ref" || members?.kind !== "contract-declaration") {
114
+ throw new Error("implementContract takes a declaration from declareContract");
115
+ }
116
+ const label = `Contract ${members.name} (${members.contractId}@${members.version})`;
117
+ const given = (implementation ?? {});
118
+ for (const key of Object.keys(given)) {
119
+ if (!["tools", "observables", "exposes", "alsoImplements"].includes(key)) {
120
+ throw new Error(`${label}: implementContract takes tools, observables, exposes, and alsoImplements, not ${key}`);
121
+ }
122
+ }
123
+ const exposes = exposedContracts(given.exposes, members, label);
124
+ const entries = (what, declared) => {
125
+ const map = given[what] ?? {};
126
+ if (typeof map !== "object" || Array.isArray(map)) {
127
+ throw new Error(`${label}: implementation ${what} must be an object by name`);
128
+ }
129
+ for (const name of Object.keys(map)) {
130
+ if (!declared.includes(name)) {
131
+ throw new Error(`${label} declares no ${what === "tools" ? "tool" : "observable"} "${name}"`);
132
+ }
133
+ }
134
+ return map;
135
+ };
136
+ const toolNames = members.tools.map((tool) => tool.definition.name);
137
+ const handlers = entries("tools", toolNames);
138
+ const tools = members.tools.map((tool) => {
139
+ const { name } = tool.definition;
140
+ const entry = Object.hasOwn(handlers, name) ? handlers[name] : undefined;
141
+ const { handler, timeoutMs, ...rest } = typeof entry === "function"
142
+ ? { handler: entry, timeoutMs: undefined }
143
+ : (entry ?? {});
144
+ if (typeof handler !== "function") {
145
+ throw new Error(`${label}: implement tool "${name}" with a handler`);
146
+ }
147
+ if (Object.keys(rest).length > 0) {
148
+ throw new Error(`${label} tool "${name}": an implementation sets handler and timeoutMs only, not ${Object.keys(rest).join(", ")}`);
149
+ }
150
+ return tool_1.defineTool({
151
+ ...tool.definition,
152
+ ...(timeoutMs === undefined ? {} : { timeoutMs }),
153
+ handler,
154
+ });
155
+ });
156
+ const observableNames = members.observables.map((observable) => observable.definition.name);
157
+ const sources = entries("observables", observableNames);
158
+ const observables = members.observables.map((member) => {
159
+ const observable = member;
160
+ const { name } = observable.definition;
161
+ const source = Object.hasOwn(sources, name) ? sources[name] : undefined;
162
+ if (source === undefined) {
163
+ throw new Error(`${label}: implement observable "${name}" with a source`);
164
+ }
165
+ return observables_1.defineObservable({
166
+ ...observable.definition,
167
+ source,
168
+ });
169
+ });
170
+ const contract = (0, define_package_1.defineContract)({
171
+ contractId: members.contractId,
172
+ version: members.version,
173
+ name: members.name,
174
+ ...(members.description === undefined ? {} : { description: members.description }),
175
+ tables: members.tables,
176
+ tools,
177
+ observables,
178
+ events: members.events,
179
+ ...(given.alsoImplements === undefined
180
+ ? {}
181
+ : { alsoImplements: given.alsoImplements }),
182
+ });
183
+ return (exposes.length
184
+ ? Object.freeze({ ...contract, exposes: Object.freeze(exposes) })
185
+ : contract);
186
+ }
187
+ /** Check an implementation's `exposes` and keep each contract's id and version. */
188
+ function exposedContracts(value, members, label) {
189
+ if (value === undefined) {
190
+ return [];
191
+ }
192
+ if (!Array.isArray(value)) {
193
+ throw new Error(`${label}: exposes must be a list of contracts`);
194
+ }
195
+ const seen = new Set();
196
+ return value.map((item) => {
197
+ const { contractId, version } = item ?? {};
198
+ if (!(0, peer_id_1.isid)(contractId) || !Number.isInteger(version) || version < 1) {
199
+ throw new Error(`${label}: exposes takes contracts (or their references) with an id and version`);
200
+ }
201
+ const key = `${contractId}@${version}`;
202
+ if (key === `${members.contractId}@${members.version}`) {
203
+ throw new Error(`${label} can't expose itself`);
204
+ }
205
+ if (seen.has(key)) {
206
+ throw new Error(`${label} exposes ${key} twice`);
207
+ }
208
+ seen.add(key);
209
+ return Object.freeze({ contractId: contractId, version: version });
210
+ });
211
+ }
212
+ /**
213
+ * True for a declaration from {@link declareContract}.
214
+ *
215
+ * @param value - A contract reference, contract, or anything else.
216
+ */
217
+ function isContractDeclaration(value) {
218
+ return (value?.kind === "contract-ref" &&
219
+ value.declaration?.kind === "contract-declaration");
220
+ }
@@ -0,0 +1 @@
1
+ export {};