@peers-app/peers-sdk 0.21.1 → 0.21.3

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 (44) hide show
  1. package/dist/context/user-context.d.ts +10 -3
  2. package/dist/context/user-context.js +12 -12
  3. package/dist/contracts/__tests__/builder.test.js +158 -4
  4. package/dist/contracts/__tests__/contract-resolvers.test.js +94 -0
  5. package/dist/contracts/__tests__/host-contract-transport.test.d.ts +1 -0
  6. package/dist/contracts/__tests__/host-contract-transport.test.js +51 -0
  7. package/dist/contracts/__tests__/registry.test.js +45 -303
  8. package/dist/contracts/__tests__/system-contracts.test.d.ts +1 -0
  9. package/dist/contracts/__tests__/system-contracts.test.js +61 -0
  10. package/dist/contracts/builder.d.ts +43 -2
  11. package/dist/contracts/builder.js +79 -5
  12. package/dist/contracts/contract-proxy.d.ts +61 -21
  13. package/dist/contracts/contract-resolvers.d.ts +20 -0
  14. package/dist/contracts/contract-resolvers.js +57 -0
  15. package/dist/contracts/create-local-consumer.d.ts +12 -0
  16. package/dist/contracts/create-local-consumer.js +19 -0
  17. package/dist/contracts/host-contract-transport.d.ts +38 -0
  18. package/dist/contracts/host-contract-transport.js +107 -0
  19. package/dist/contracts/index.d.ts +8 -4
  20. package/dist/contracts/index.js +29 -1
  21. package/dist/contracts/registry.d.ts +17 -0
  22. package/dist/contracts/registry.js +36 -0
  23. package/dist/contracts/system/device-operations-contract.js +7 -0
  24. package/dist/contracts/system/index.d.ts +10 -0
  25. package/dist/contracts/system/index.js +38 -0
  26. package/dist/contracts/system/logs-contract.d.ts +18 -1
  27. package/dist/contracts/system/logs-contract.js +8 -2
  28. package/dist/contracts/system/network-contracts.d.ts +231 -0
  29. package/dist/contracts/system/network-contracts.js +192 -0
  30. package/dist/contracts/system-contracts.d.ts +47 -0
  31. package/dist/contracts/system-contracts.js +69 -0
  32. package/dist/contracts/types.d.ts +44 -0
  33. package/dist/package-loader/contract-package-loader.test.d.ts +1 -0
  34. package/dist/package-loader/contract-package-loader.test.js +88 -0
  35. package/dist/package-loader/package-loader.d.ts +8 -0
  36. package/dist/package-loader/package-loader.js +17 -1
  37. package/dist/package-loader/package-loader.test.js +17 -0
  38. package/dist/package-loader/resolve-consumed-contracts.d.ts +13 -0
  39. package/dist/package-loader/resolve-consumed-contracts.js +55 -0
  40. package/dist/package-loader/resolve-consumed-contracts.test.d.ts +1 -0
  41. package/dist/package-loader/resolve-consumed-contracts.test.js +123 -0
  42. package/dist/system-ids.d.ts +4 -0
  43. package/dist/system-ids.js +5 -1
  44. package/package.json +1 -1
@@ -1,8 +1,25 @@
1
1
  import type { DataContext } from "../../context/data-context";
2
- import type { IContractResolution } from "../contract-proxy";
2
+ import { ConsoleLogsTable } from "../../logging/console-logs.table";
3
+ import type { IContractConsumerBase, IContractResolution, ITableProxy } from "../contract-proxy";
3
4
  import type { IContractDefinition } from "../types";
4
5
  /** Version of the built-in System Logs contract. */
5
6
  export declare const LOGS_CONTRACT_VERSION = 1;
7
+ /**
8
+ * Consumer-side TypeScript shape for the System Logs contract.
9
+ *
10
+ * Hand-maintained for now so packages can narrow `pkg.consumes(...)` (e.g.
11
+ * `pkg.consumes<ILogsConsumer>(logsContractId, 1)`). Expect this to be
12
+ * replaced by types generated from package/contract definitions.
13
+ *
14
+ * Omits empty `tools` / `events` / `observables` bags. `ConsoleLogs` is an
15
+ * {@link ITableProxy} of the remotely callable table surface — not a literal
16
+ * {@link ConsoleLogsTable} instance.
17
+ */
18
+ export interface ILogsConsumer extends IContractConsumerBase {
19
+ tables: {
20
+ ConsoleLogs: ITableProxy<ConsoleLogsTable, "deleteOldLogs">;
21
+ };
22
+ }
6
23
  /**
7
24
  * The first built-in **system contract**: read and write the local device's console logs.
8
25
  *
@@ -7,7 +7,7 @@ const user_context_singleton_1 = require("../../context/user-context-singleton")
7
7
  const types_1 = require("../../data/orm/types");
8
8
  const console_logs_table_1 = require("../../logging/console-logs.table");
9
9
  const system_ids_1 = require("../../system-ids");
10
- const contract_resolvers_1 = require("../contract-resolvers");
10
+ const system_contracts_1 = require("../system-contracts");
11
11
  /** Version of the built-in System Logs contract. */
12
12
  exports.LOGS_CONTRACT_VERSION = 1;
13
13
  let _definition;
@@ -57,4 +57,10 @@ function resolveLogsContract(ctx) {
57
57
  tables: { [console_logs_table_1.consoleLogsMetaData.name]: consoleLogs },
58
58
  };
59
59
  }
60
- (0, contract_resolvers_1.registerContractResolver)(system_ids_1.logsContractId, exports.LOGS_CONTRACT_VERSION, resolveLogsContract);
60
+ (0, system_contracts_1.registerSystemContract)({
61
+ providerPackageId: system_ids_1.peersSystemPackageId,
62
+ contractId: system_ids_1.logsContractId,
63
+ version: exports.LOGS_CONTRACT_VERSION,
64
+ getDefinition: getLogsContractDefinition,
65
+ resolve: resolveLogsContract,
66
+ });
@@ -0,0 +1,231 @@
1
+ import type { TrustLevel } from "../../device/socket.type";
2
+ import type { IConsoleLog } from "../../logging/console-logs.table";
3
+ import type { Observable } from "../../observable";
4
+ import type { INetworkInfo } from "../../types/peer-device";
5
+ import type { IContractConsumerBase } from "../contract-proxy";
6
+ import type { IContractDefinition } from "../types";
7
+ /** Version of the built-in System Network Diagnostics contract. */
8
+ export declare const NETWORK_DIAGNOSTICS_CONTRACT_VERSION = 1;
9
+ /** Version of the built-in System Network Control contract. */
10
+ export declare const NETWORK_CONTROL_CONTRACT_VERSION = 1;
11
+ /** Stable IDs for tools in System Network Diagnostics v1. */
12
+ export declare const networkDiagnosticsToolIds: {
13
+ readonly getOverview: "00ms1yb50ym353ads0gel5jpv";
14
+ readonly getConnections: "00ms1yb50ykny9kdgiclpa1t4";
15
+ readonly getGroupSyncStatus: "00ms1yb50yp2q7jr0jglzsztq";
16
+ readonly getDeviceDetails: "00ms1yb50yw792rslve1q99qg";
17
+ readonly getGroupDetails: "00ms1yb50yuru8h1fg4t9na3e";
18
+ readonly getDisconnectedDevices: "00ms1yb50y3jpoby5zomltahr";
19
+ readonly queryRemoteLogs: "00ms1yb50y2fbfnth22yz52eu";
20
+ };
21
+ /** Stable IDs for tools in System Network Control v1. */
22
+ export declare const networkControlToolIds: {
23
+ readonly refreshNetworkInfo: "00ms1yb50y9rsdyqmr81vjoli";
24
+ readonly connectToDevice: "00ms1yb50y40ty8tr0sic875x";
25
+ readonly disconnectDevice: "00ms1yb50yqvboqmhshqvlibr";
26
+ readonly deleteDevice: "00ms1yb50y5mc448nuavlex86";
27
+ readonly syncGroupNow: "00ms1yb50ylnqlra26jx232py";
28
+ readonly resetChangeTracking: "00ms1yb50yfuackpl1w37hmxc";
29
+ };
30
+ /** Overall status shown by the shell's compact network indicator. */
31
+ export type NetworkStatusState = "offline" | "syncing" | "synced" | "error";
32
+ /** Runtime synchronization state for one personal or shared-group context. */
33
+ export type NetworkSyncState = "idle" | "syncing" | "error";
34
+ /** Safe, bounded synchronization error detail suitable for local UI display. */
35
+ export interface INetworkSyncError {
36
+ dataContextId: string;
37
+ message: string;
38
+ occurredAt: number;
39
+ }
40
+ /** Reactive summary consumed by the tabs-strip Network Status indicator. */
41
+ export interface INetworkStatusSummary {
42
+ state: NetworkStatusState;
43
+ connectionCount: number;
44
+ syncingContextCount: number;
45
+ errorCount: number;
46
+ lastSuccessfulSyncAt?: number;
47
+ errors: INetworkSyncError[];
48
+ }
49
+ /** Current synchronization lifecycle for one data context. */
50
+ export interface IDataContextSyncStatus {
51
+ dataContextId: string;
52
+ state: NetworkSyncState;
53
+ lastSuccessfulSyncAt?: number;
54
+ lastErrorAt?: number;
55
+ lastError?: string;
56
+ }
57
+ /** Connection/member counts for one personal or shared group. */
58
+ export interface INetworkGroupSummary {
59
+ groupId: string;
60
+ groupName: string;
61
+ connectedDevices: number;
62
+ totalMembers: number;
63
+ }
64
+ /** Portable overview of the local device's network state. */
65
+ export interface INetworkOverview {
66
+ localDeviceId: string;
67
+ localUserId: string;
68
+ totalConnections: number;
69
+ availableSlots: number;
70
+ maxConnections: number;
71
+ cpuPercent: number;
72
+ memPercent: number;
73
+ groups: INetworkGroupSummary[];
74
+ }
75
+ /** Detailed portable information about one active device connection. */
76
+ export interface INetworkConnectionInfo {
77
+ deviceId: string;
78
+ userId: string;
79
+ userName?: string;
80
+ deviceName?: string;
81
+ userTrustLevel: TrustLevel;
82
+ deviceTrustLevel: TrustLevel;
83
+ connectionState: "connected" | "syncing" | "idle";
84
+ sharedGroups: string[];
85
+ roles: Record<string, string>;
86
+ pathType: "direct" | "indirect" | "unknown";
87
+ throughDeviceIds?: string[];
88
+ latencyMs: number;
89
+ errorRate: number;
90
+ isServer: boolean;
91
+ connectionAddress?: string;
92
+ bytesSent?: number;
93
+ bytesReceived?: number;
94
+ sendRateMBps?: number;
95
+ receiveRateMBps?: number;
96
+ }
97
+ /** Serializable synchronization connection detail for one group. */
98
+ export interface INetworkSyncConnection {
99
+ deviceId: string;
100
+ latencyMs: number;
101
+ errorRate: number;
102
+ timestampLastApplied?: number;
103
+ closed?: boolean;
104
+ }
105
+ /** Synchronization status and topology for one data context. */
106
+ export interface INetworkGroupSyncInfo {
107
+ groupId: string;
108
+ groupName: string;
109
+ connectedDevices: INetworkSyncConnection[];
110
+ preferredDeviceIds: string[];
111
+ lastSyncTimestamp: number;
112
+ totalMembers: number;
113
+ syncStatus: IDataContextSyncStatus;
114
+ }
115
+ /** Detailed portable information about one connected device. */
116
+ export interface INetworkDeviceDetails extends INetworkConnectionInfo {
117
+ canReadRemoteLogs: boolean;
118
+ networkInfo?: INetworkInfo;
119
+ syncStatsByGroup: Record<string, {
120
+ lastSyncTime: number;
121
+ isPreferred: boolean;
122
+ }>;
123
+ }
124
+ /** A known device that does not currently have an active connection. */
125
+ export interface INetworkDisconnectedDevice {
126
+ deviceId: string;
127
+ userId: string;
128
+ userName?: string;
129
+ trustLevel: TrustLevel;
130
+ firstSeen: Date;
131
+ lastSeen: Date;
132
+ name?: string;
133
+ serverUrl?: string;
134
+ }
135
+ /** One member shown in Network Viewer's group detail. */
136
+ export interface INetworkGroupMember {
137
+ userId: string;
138
+ userName?: string;
139
+ role: string;
140
+ trustLevel: TrustLevel;
141
+ }
142
+ /** Detailed portable membership information for one data context. */
143
+ export interface INetworkGroupDetails {
144
+ groupId: string;
145
+ groupName: string;
146
+ founderUserId: string;
147
+ founderUserName?: string;
148
+ members: INetworkGroupMember[];
149
+ }
150
+ /** Filters and bounds for a directly connected device's System Logs query. */
151
+ export interface INetworkRemoteLogsQuery {
152
+ sinceTimestamp?: number;
153
+ level?: IConsoleLog["level"];
154
+ process?: string;
155
+ search?: string;
156
+ pageSize?: number;
157
+ timeoutMs?: number;
158
+ }
159
+ /** Bounded remote logs returned through System Network Diagnostics. */
160
+ export interface INetworkRemoteLogsResult {
161
+ deviceId: string;
162
+ truncated: boolean;
163
+ logs: IConsoleLog[];
164
+ queriedAt: number;
165
+ }
166
+ /** Structured result returned by every System Network Control operation. */
167
+ export interface INetworkControlResult {
168
+ success: boolean;
169
+ message: string;
170
+ }
171
+ /** Typed consumer proxy for System Network Diagnostics v1. */
172
+ export interface INetworkDiagnosticsConsumer extends IContractConsumerBase {
173
+ tools: {
174
+ getOverview(): Promise<{
175
+ overview: INetworkOverview;
176
+ }>;
177
+ getConnections(): Promise<{
178
+ connections: INetworkConnectionInfo[];
179
+ }>;
180
+ getGroupSyncStatus(input?: {
181
+ groupId?: string;
182
+ }): Promise<{
183
+ groups: INetworkGroupSyncInfo[];
184
+ }>;
185
+ getDeviceDetails(input: {
186
+ deviceId: string;
187
+ }): Promise<{
188
+ device?: INetworkDeviceDetails;
189
+ }>;
190
+ getGroupDetails(input: {
191
+ groupId: string;
192
+ }): Promise<{
193
+ group?: INetworkGroupDetails;
194
+ }>;
195
+ getDisconnectedDevices(): Promise<{
196
+ devices: INetworkDisconnectedDevice[];
197
+ }>;
198
+ queryRemoteLogs(input: {
199
+ deviceId: string;
200
+ query?: INetworkRemoteLogsQuery;
201
+ }): Promise<INetworkRemoteLogsResult>;
202
+ };
203
+ observables: {
204
+ status: Observable<INetworkStatusSummary>;
205
+ };
206
+ }
207
+ /** Typed consumer proxy for System Network Control v1. */
208
+ export interface INetworkControlConsumer extends IContractConsumerBase {
209
+ tools: {
210
+ refreshNetworkInfo(): Promise<INetworkControlResult>;
211
+ connectToDevice(input: {
212
+ deviceId: string;
213
+ }): Promise<INetworkControlResult>;
214
+ disconnectDevice(input: {
215
+ deviceId: string;
216
+ }): Promise<INetworkControlResult>;
217
+ deleteDevice(input: {
218
+ deviceId: string;
219
+ }): Promise<INetworkControlResult>;
220
+ syncGroupNow(input: {
221
+ groupId: string;
222
+ }): Promise<INetworkControlResult>;
223
+ resetChangeTracking(input: {
224
+ dataContextId: string;
225
+ }): Promise<INetworkControlResult>;
226
+ };
227
+ }
228
+ /** Return the portable read-only network diagnostics contract shape. */
229
+ export declare function getNetworkDiagnosticsContractDefinition(): IContractDefinition;
230
+ /** Return the explicit mutating local network control contract shape. */
231
+ export declare function getNetworkControlContractDefinition(): IContractDefinition;
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.networkControlToolIds = exports.networkDiagnosticsToolIds = exports.NETWORK_CONTROL_CONTRACT_VERSION = exports.NETWORK_DIAGNOSTICS_CONTRACT_VERSION = void 0;
4
+ exports.getNetworkDiagnosticsContractDefinition = getNetworkDiagnosticsContractDefinition;
5
+ exports.getNetworkControlContractDefinition = getNetworkControlContractDefinition;
6
+ const system_ids_1 = require("../../system-ids");
7
+ const field_type_1 = require("../../types/field-type");
8
+ const system_contracts_1 = require("../system-contracts");
9
+ /** Version of the built-in System Network Diagnostics contract. */
10
+ exports.NETWORK_DIAGNOSTICS_CONTRACT_VERSION = 1;
11
+ /** Version of the built-in System Network Control contract. */
12
+ exports.NETWORK_CONTROL_CONTRACT_VERSION = 1;
13
+ /** Stable IDs for tools in System Network Diagnostics v1. */
14
+ exports.networkDiagnosticsToolIds = {
15
+ getOverview: "00ms1yb50ym353ads0gel5jpv",
16
+ getConnections: "00ms1yb50ykny9kdgiclpa1t4",
17
+ getGroupSyncStatus: "00ms1yb50yp2q7jr0jglzsztq",
18
+ getDeviceDetails: "00ms1yb50yw792rslve1q99qg",
19
+ getGroupDetails: "00ms1yb50yuru8h1fg4t9na3e",
20
+ getDisconnectedDevices: "00ms1yb50y3jpoby5zomltahr",
21
+ queryRemoteLogs: "00ms1yb50y2fbfnth22yz52eu",
22
+ };
23
+ /** Stable IDs for tools in System Network Control v1. */
24
+ exports.networkControlToolIds = {
25
+ refreshNetworkInfo: "00ms1yb50y9rsdyqmr81vjoli",
26
+ connectToDevice: "00ms1yb50y40ty8tr0sic875x",
27
+ disconnectDevice: "00ms1yb50yqvboqmhshqvlibr",
28
+ deleteDevice: "00ms1yb50y5mc448nuavlex86",
29
+ syncGroupNow: "00ms1yb50ylnqlra26jx232py",
30
+ resetChangeTracking: "00ms1yb50yfuackpl1w37hmxc",
31
+ };
32
+ const field = (name, type, description, opts = {}) => ({ name, type, description, ...opts });
33
+ let diagnosticsDefinition;
34
+ let controlDefinition;
35
+ /** Return the portable read-only network diagnostics contract shape. */
36
+ function getNetworkDiagnosticsContractDefinition() {
37
+ diagnosticsDefinition ??= {
38
+ contractId: system_ids_1.networkDiagnosticsContractId,
39
+ version: exports.NETWORK_DIAGNOSTICS_CONTRACT_VERSION,
40
+ devTag: "dev",
41
+ name: "System Network Diagnostics",
42
+ description: "Portable local network, connection, and synchronization diagnostics.",
43
+ tables: [],
44
+ tools: [
45
+ {
46
+ name: "getOverview",
47
+ usageDescription: "Return aggregate network and group information.",
48
+ inputFields: [],
49
+ outputFields: [field("overview", field_type_1.FieldType.object, "Local network overview.")],
50
+ },
51
+ {
52
+ name: "getConnections",
53
+ usageDescription: "List active device connections and their health.",
54
+ inputFields: [],
55
+ outputFields: [
56
+ field("connections", field_type_1.FieldType.object, "Active connection details.", { isArray: true }),
57
+ ],
58
+ },
59
+ {
60
+ name: "getGroupSyncStatus",
61
+ usageDescription: "Return sync status for one context or every local context.",
62
+ inputFields: [
63
+ field("groupId", field_type_1.FieldType.id, "Optional personal or group context ID.", {
64
+ optional: true,
65
+ }),
66
+ ],
67
+ outputFields: [
68
+ field("groups", field_type_1.FieldType.object, "Group synchronization details.", { isArray: true }),
69
+ ],
70
+ },
71
+ {
72
+ name: "getDeviceDetails",
73
+ usageDescription: "Return details for one currently connected device.",
74
+ inputFields: [field("deviceId", field_type_1.FieldType.id, "Connected device ID.")],
75
+ outputFields: [
76
+ field("device", field_type_1.FieldType.object, "Connected device details.", { optional: true }),
77
+ ],
78
+ },
79
+ {
80
+ name: "getGroupDetails",
81
+ usageDescription: "Return membership details for one local data context.",
82
+ inputFields: [field("groupId", field_type_1.FieldType.id, "Personal or group context ID.")],
83
+ outputFields: [
84
+ field("group", field_type_1.FieldType.object, "Group membership details.", { optional: true }),
85
+ ],
86
+ },
87
+ {
88
+ name: "getDisconnectedDevices",
89
+ usageDescription: "List known devices without an active connection.",
90
+ inputFields: [],
91
+ outputFields: [
92
+ field("devices", field_type_1.FieldType.object, "Disconnected device details.", { isArray: true }),
93
+ ],
94
+ },
95
+ {
96
+ name: "queryRemoteLogs",
97
+ usageDescription: "Query bounded logs from a directly connected authorized device.",
98
+ inputFields: [
99
+ field("deviceId", field_type_1.FieldType.id, "Connected device ID."),
100
+ field("query", field_type_1.FieldType.object, "Optional remote log filters.", { optional: true }),
101
+ ],
102
+ outputFields: [
103
+ field("deviceId", field_type_1.FieldType.id, "Queried device ID."),
104
+ field("truncated", field_type_1.FieldType.boolean, "Whether matching rows were omitted."),
105
+ field("logs", field_type_1.FieldType.object, "Matching console logs.", { isArray: true }),
106
+ field("queriedAt", field_type_1.FieldType.number, "Local completion timestamp."),
107
+ ],
108
+ },
109
+ ],
110
+ observables: [
111
+ {
112
+ name: "status",
113
+ description: "Reactive connection and synchronization status summary.",
114
+ valueType: field_type_1.FieldType.object,
115
+ writable: false,
116
+ },
117
+ ],
118
+ events: [],
119
+ };
120
+ return diagnosticsDefinition;
121
+ }
122
+ /** Return the explicit mutating local network control contract shape. */
123
+ function getNetworkControlContractDefinition() {
124
+ const deviceInput = [field("deviceId", field_type_1.FieldType.id, "Target device ID.")];
125
+ const resultFields = [
126
+ field("success", field_type_1.FieldType.boolean, "Whether the operation completed successfully."),
127
+ field("message", field_type_1.FieldType.string, "Human-readable operation result."),
128
+ ];
129
+ controlDefinition ??= {
130
+ contractId: system_ids_1.networkControlContractId,
131
+ version: exports.NETWORK_CONTROL_CONTRACT_VERSION,
132
+ devTag: "dev",
133
+ name: "System Network Control",
134
+ description: "Explicit local device connection and synchronization control operations.",
135
+ tables: [],
136
+ tools: [
137
+ {
138
+ name: "refreshNetworkInfo",
139
+ usageDescription: "Refresh network information and preferred connection choices.",
140
+ inputFields: [],
141
+ outputFields: resultFields,
142
+ },
143
+ {
144
+ name: "connectToDevice",
145
+ usageDescription: "Start a connection attempt to one known device.",
146
+ inputFields: deviceInput,
147
+ outputFields: resultFields,
148
+ },
149
+ {
150
+ name: "disconnectDevice",
151
+ usageDescription: "Close the active connection to one device.",
152
+ inputFields: deviceInput,
153
+ outputFields: resultFields,
154
+ },
155
+ {
156
+ name: "deleteDevice",
157
+ usageDescription: "Forget one known, disconnected device.",
158
+ inputFields: deviceInput,
159
+ outputFields: resultFields,
160
+ },
161
+ {
162
+ name: "syncGroupNow",
163
+ usageDescription: "Notify connected devices of changes in one data context.",
164
+ inputFields: [field("groupId", field_type_1.FieldType.id, "Personal or group context ID.")],
165
+ outputFields: resultFields,
166
+ },
167
+ {
168
+ name: "resetChangeTracking",
169
+ usageDescription: "Reset one data context's change tracking for an expensive full sync.",
170
+ inputFields: [
171
+ field("dataContextId", field_type_1.FieldType.id, "Personal or group context ID to reset."),
172
+ ],
173
+ outputFields: resultFields,
174
+ },
175
+ ],
176
+ observables: [],
177
+ events: [],
178
+ };
179
+ return controlDefinition;
180
+ }
181
+ (0, system_contracts_1.registerSystemContract)({
182
+ providerPackageId: system_ids_1.peersSystemPackageId,
183
+ contractId: system_ids_1.networkDiagnosticsContractId,
184
+ version: exports.NETWORK_DIAGNOSTICS_CONTRACT_VERSION,
185
+ getDefinition: getNetworkDiagnosticsContractDefinition,
186
+ });
187
+ (0, system_contracts_1.registerSystemContract)({
188
+ providerPackageId: system_ids_1.peersSystemPackageId,
189
+ contractId: system_ids_1.networkControlContractId,
190
+ version: exports.NETWORK_CONTROL_CONTRACT_VERSION,
191
+ getDefinition: getNetworkControlContractDefinition,
192
+ });
@@ -0,0 +1,47 @@
1
+ import type { ContractResolver } from "./contract-resolvers";
2
+ import type { ContractRegistry } from "./registry";
3
+ import type { IContractDefinition } from "./types";
4
+ /**
5
+ * A built-in system contract that should appear in every data context's
6
+ * {@link ContractRegistry} without being installed as a user package.
7
+ */
8
+ export interface ISystemContractRegistration {
9
+ /** Synthetic provider package id (typically `peersSystemPackageId`). */
10
+ providerPackageId: string;
11
+ /**
12
+ * Lazy definition builder. Kept lazy so contracts like Logs can defer schema
13
+ * access until after module initialization completes.
14
+ */
15
+ getDefinition: () => IContractDefinition;
16
+ /**
17
+ * Optional live resolver for contract calls. When provided, `contractId` and
18
+ * `version` must also be set so the resolver can be keyed without building
19
+ * the definition at registration time.
20
+ */
21
+ resolve?: ContractResolver;
22
+ /** Required when {@link resolve} is set — resolver map key without calling `getDefinition`. */
23
+ contractId?: string;
24
+ /** Required when {@link resolve} is set. */
25
+ version?: number;
26
+ }
27
+ /**
28
+ * Self-register a built-in system contract.
29
+ *
30
+ * Call once from the contract module (side effect at import). Later
31
+ * {@link installSystemContracts} installs every registered entry into a
32
+ * concrete registry. New system contracts only need this one call.
33
+ */
34
+ export declare function registerSystemContract(registration: ISystemContractRegistration): void;
35
+ /**
36
+ * Register every known system contract into `registry` as a provider.
37
+ * Safe to call more than once for the same registry (provider updates in place).
38
+ */
39
+ export declare function installSystemContracts(registry: ContractRegistry): void;
40
+ /** Snapshot of registered system contracts (for tests and diagnostics). */
41
+ export declare function listSystemContracts(): readonly ISystemContractRegistration[];
42
+ /**
43
+ * Clear the system-contract catalog. Test-only — production code must not call this.
44
+ *
45
+ * @internal
46
+ */
47
+ export declare function _clearSystemContractsForTests(): void;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerSystemContract = registerSystemContract;
4
+ exports.installSystemContracts = installSystemContracts;
5
+ exports.listSystemContracts = listSystemContracts;
6
+ exports._clearSystemContractsForTests = _clearSystemContractsForTests;
7
+ const systemContracts = [];
8
+ function systemContractKey(contractId, version) {
9
+ return `${contractId}@${version}`;
10
+ }
11
+ /**
12
+ * Self-register a built-in system contract.
13
+ *
14
+ * Call once from the contract module (side effect at import). Later
15
+ * {@link installSystemContracts} installs every registered entry into a
16
+ * concrete registry. New system contracts only need this one call.
17
+ */
18
+ function registerSystemContract(registration) {
19
+ if (registration.resolve) {
20
+ if (!registration.contractId || registration.version == null) {
21
+ throw new Error("registerSystemContract: contractId and version are required when resolve is provided");
22
+ }
23
+ // Defer resolver registration so self-registration during SDK barrel / package-loader
24
+ // import cannot re-enter contract-resolvers mid-initialization.
25
+ const { contractId, version, resolve } = registration;
26
+ queueMicrotask(() => {
27
+ const { registerContractResolver } = require("./contract-resolvers");
28
+ registerContractResolver(contractId, version, resolve);
29
+ });
30
+ }
31
+ const key = registration.contractId && registration.version != null
32
+ ? systemContractKey(registration.contractId, registration.version)
33
+ : undefined;
34
+ if (key) {
35
+ const existingIdx = systemContracts.findIndex((entry) => entry.contractId &&
36
+ entry.version != null &&
37
+ systemContractKey(entry.contractId, entry.version) === key);
38
+ if (existingIdx >= 0) {
39
+ systemContracts[existingIdx] = registration;
40
+ return;
41
+ }
42
+ }
43
+ systemContracts.push(registration);
44
+ }
45
+ /**
46
+ * Register every known system contract into `registry` as a provider.
47
+ * Safe to call more than once for the same registry (provider updates in place).
48
+ */
49
+ function installSystemContracts(registry) {
50
+ for (const entry of systemContracts) {
51
+ const definition = entry.getDefinition();
52
+ const result = registry.register(entry.providerPackageId, definition);
53
+ if (!result.valid) {
54
+ console.error(`[SystemContracts] Failed to register ${definition.name} (${definition.contractId}@${definition.version}):`, result.errors);
55
+ }
56
+ }
57
+ }
58
+ /** Snapshot of registered system contracts (for tests and diagnostics). */
59
+ function listSystemContracts() {
60
+ return systemContracts;
61
+ }
62
+ /**
63
+ * Clear the system-contract catalog. Test-only — production code must not call this.
64
+ *
65
+ * @internal
66
+ */
67
+ function _clearSystemContractsForTests() {
68
+ systemContracts.length = 0;
69
+ }
@@ -4,6 +4,7 @@ import type { IToolInstance } from "../data/tools";
4
4
  import type { Event } from "../events";
5
5
  import type { Observable } from "../observable";
6
6
  import type { FieldType, IField } from "../types/field-type";
7
+ import type { IContractConsumer, IContractConsumerBase } from "./contract-proxy";
7
8
  /**
8
9
  * A versioned interface definition declaring the shape of tables, tools,
9
10
  * observables, and events that a package provides. Pure data — no executable code.
@@ -58,6 +59,43 @@ export interface IContractEvent {
58
59
  /** Shape of the payload delivered to subscribers when the event fires. */
59
60
  payloadFields: IField[];
60
61
  }
62
+ /**
63
+ * Options for {@link PackageBuilder.consumes}.
64
+ *
65
+ * Provider selection (`providerPackageIds`, `fallbackToDefaultProvider`) is
66
+ * recorded here for the package-loader; wiring that resolves the deferred
67
+ * handle is a follow-up step.
68
+ */
69
+ export interface IConsumedContractOptions {
70
+ /**
71
+ * When true, a missing provider settles the handle with `undefined` instead
72
+ * of rejecting. Defaults to false (required).
73
+ */
74
+ optional?: boolean;
75
+ /**
76
+ * Ordered preference of provider package IDs. The loader tries these in
77
+ * order before considering the active/default provider.
78
+ */
79
+ providerPackageIds?: string[];
80
+ /**
81
+ * When true and none of {@link providerPackageIds} is available, fall back
82
+ * to the active/default provider for the contract. Ignored when
83
+ * `providerPackageIds` is omitted (default provider is used directly).
84
+ */
85
+ fallbackToDefaultProvider?: boolean;
86
+ }
87
+ /**
88
+ * Deferred handle returned by {@link PackageBuilder.consumes}.
89
+ *
90
+ * The handle itself is not thenable — await {@link consumer} from runtime
91
+ * code after `definePackage` finishes, not inside the define callback.
92
+ * Settlement is owned by the SDK (package-loader); package code cannot
93
+ * resolve or reject the promise.
94
+ */
95
+ export interface IConsumedContractHandle<T extends IContractConsumerBase | undefined = IContractConsumer> {
96
+ /** Resolves to the live consumer proxy, or `undefined` when optional and unmatched. */
97
+ readonly consumer: Promise<T>;
98
+ }
61
99
  /**
62
100
  * A reference to a contract that a package wants to consume.
63
101
  * Recorded during `definePackage` and checked at install time.
@@ -66,6 +104,12 @@ export interface IConsumedContract {
66
104
  contractId: string;
67
105
  version: number;
68
106
  optional?: boolean;
107
+ /** Ordered preferred provider package IDs, if any. */
108
+ providerPackageIds?: string[];
109
+ /** Whether to fall back to the default provider when preferred ones are missing. */
110
+ fallbackToDefaultProvider?: boolean;
111
+ /** Deferred handle returned by `consumes()` for this dependency. */
112
+ handle?: IConsumedContractHandle<IContractConsumerBase | undefined>;
69
113
  }
70
114
  /**
71
115
  * Declares that the owning contract's implementation also satisfies another