@xyo-network/xl1-browser-system 5.0.11 → 5.0.13
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.
- package/README.md +229 -11
- package/dist/browser/Xl1BrowserConfig.d.ts +3 -0
- package/dist/browser/Xl1BrowserConfig.d.ts.map +1 -1
- package/dist/browser/Xl1BrowserProvider.d.ts +4 -0
- package/dist/browser/Xl1BrowserProvider.d.ts.map +1 -1
- package/dist/browser/index.mjs +135 -125
- package/dist/browser/index.mjs.map +4 -4
- package/package.json +12 -4
package/README.md
CHANGED
|
@@ -4,30 +4,248 @@ Config-driven XL1 provider actor systems for browser pages, workers, service
|
|
|
4
4
|
workers, and extension background realms.
|
|
5
5
|
|
|
6
6
|
The package adapts XL1's provider catalog to browser-kit's neutral planner.
|
|
7
|
-
Configuration is
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
Configuration is resolved once, one XL1 `ProviderFactoryLocator` is provisioned
|
|
8
|
+
in the owner realm, and every selected actor receives that same resolved
|
|
9
|
+
provider system with its own actor configuration.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
Install the XL1 integration and only the realm adapters the application uses:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
pnpm add @xyo-network/xl1-browser-system \
|
|
17
|
+
@ariestools/browser-kit-page \
|
|
18
|
+
@ariestools/browser-kit-worker \
|
|
19
|
+
@ariestools/browser-kit-service-worker \
|
|
20
|
+
@ariestools/browser-kit-plugin
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Configuration
|
|
24
|
+
|
|
25
|
+
Create the configuration as data. The host selects which realm constructs the
|
|
26
|
+
actor; it does not select a different provider graph for that actor.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { createXl1RestBrowserSystemConfig } from '@xyo-network/xl1-browser-system'
|
|
30
|
+
|
|
31
|
+
export function xl1ConfigFor(host: string) {
|
|
32
|
+
return createXl1RestBrowserSystemConfig({
|
|
33
|
+
endpoint: 'https://sample.mainnet.xyo.space',
|
|
34
|
+
host,
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The resulting object contains actor selections, named connections, and provider
|
|
40
|
+
bindings. It contains no module paths or executable code.
|
|
41
|
+
|
|
42
|
+
For local gateways that publish buckets under one path-based origin rather than
|
|
43
|
+
the standard `blocks.*`, `state.*`, and `indexes.*` subdomains, set
|
|
44
|
+
`layout: 'path'`:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
const localConfig = createXl1RestBrowserSystemConfig({
|
|
48
|
+
endpoint: 'https://chain.aries.test:8791',
|
|
49
|
+
host: 'page',
|
|
50
|
+
layout: 'path',
|
|
51
|
+
})
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
When adding a custom provider candidate, pass a stable explicit identifier to
|
|
55
|
+
`providerCandidateFromClass`. Constructor names can be changed by production
|
|
56
|
+
minifiers and must not become configuration identifiers:
|
|
10
57
|
|
|
11
58
|
```ts
|
|
59
|
+
const candidate = providerCandidateFromClass(
|
|
60
|
+
MyBrowserProvider,
|
|
61
|
+
'com.example.my-browser-provider',
|
|
62
|
+
)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Page
|
|
66
|
+
|
|
67
|
+
The page owns the system until navigation or discard:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { bindPageLifecycle } from '@ariestools/browser-kit-page'
|
|
12
71
|
import {
|
|
13
|
-
createXl1RestBrowserSystemConfig,
|
|
14
72
|
launchXl1BrowserSystem,
|
|
15
73
|
Xl1BrowserSystemActor,
|
|
16
74
|
} from '@xyo-network/xl1-browser-system'
|
|
17
75
|
|
|
18
|
-
|
|
19
|
-
|
|
76
|
+
import { xl1ConfigFor } from './xl1Config.ts'
|
|
77
|
+
|
|
78
|
+
const session = await launchXl1BrowserSystem({
|
|
79
|
+
config: xl1ConfigFor('page'),
|
|
20
80
|
host: 'page',
|
|
21
81
|
})
|
|
22
|
-
|
|
23
|
-
|
|
82
|
+
bindPageLifecycle(session, {
|
|
83
|
+
onStopError: error => console.error('XL1 page system failed to stop', error),
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
const actor = session.actors.find(actor => actor instanceof Xl1BrowserSystemActor)
|
|
87
|
+
if (actor === undefined) throw new Error('XL1 page system actor was not created')
|
|
24
88
|
const gateway = await actor.getGateway()
|
|
25
89
|
const blockNumber = await gateway.connection.viewer?.block.currentBlockNumber()
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
See the [executable page example](https://github.com/XYOracleNetwork/xl1-protocol/blob/v/5/packages/browser-system/examples/page.ts).
|
|
93
|
+
|
|
94
|
+
## Web worker
|
|
95
|
+
|
|
96
|
+
The worker launches the same system and binds explicit shutdown handling:
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
/// <reference lib="webworker" />
|
|
100
|
+
|
|
101
|
+
import { bindWorkerShutdown } from '@ariestools/browser-kit-worker'
|
|
102
|
+
import { launchXl1BrowserSystem } from '@xyo-network/xl1-browser-system'
|
|
103
|
+
|
|
104
|
+
import { xl1ConfigFor } from './xl1Config.ts'
|
|
105
|
+
|
|
106
|
+
const session = await launchXl1BrowserSystem({
|
|
107
|
+
config: xl1ConfigFor('worker'),
|
|
108
|
+
host: 'worker',
|
|
109
|
+
})
|
|
110
|
+
bindWorkerShutdown(self, session, {
|
|
111
|
+
onStopError: error => console.error('XL1 worker system failed to stop', error),
|
|
112
|
+
})
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Create it from the owning page with a module worker. Send
|
|
116
|
+
`{ type: 'browser-kit:shutdown' }` when the worker should stop and wait for the
|
|
117
|
+
`browser-kit:stopped` acknowledgement before terminating it.
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
const worker = new Worker(new URL('./xl1.worker.ts', import.meta.url), {
|
|
121
|
+
type: 'module',
|
|
122
|
+
})
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
See the executable [worker owner](https://github.com/XYOracleNetwork/xl1-protocol/blob/v/5/packages/browser-system/examples/xl1.worker.ts)
|
|
126
|
+
and [page client](https://github.com/XYOracleNetwork/xl1-protocol/blob/v/5/packages/browser-system/examples/worker.ts).
|
|
127
|
+
|
|
128
|
+
## Service worker
|
|
129
|
+
|
|
130
|
+
A service worker reconstructs the system once per browser-managed worker
|
|
131
|
+
incarnation. Attach every operation to the triggering event lifetime:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
/// <reference lib="webworker" />
|
|
135
|
+
|
|
136
|
+
import { ServiceWorkerSystemHost } from '@ariestools/browser-kit-service-worker'
|
|
137
|
+
import {
|
|
138
|
+
launchXl1BrowserSystem,
|
|
139
|
+
Xl1BrowserSystemActor,
|
|
140
|
+
} from '@xyo-network/xl1-browser-system'
|
|
141
|
+
|
|
142
|
+
import { xl1ConfigFor } from './xl1Config.ts'
|
|
143
|
+
|
|
144
|
+
const systemHost = new ServiceWorkerSystemHost(async () =>
|
|
145
|
+
await launchXl1BrowserSystem({
|
|
146
|
+
config: xl1ConfigFor('service-worker'),
|
|
147
|
+
host: 'service-worker',
|
|
148
|
+
identity: {
|
|
149
|
+
planId: 'my-xl1-service-worker:v1',
|
|
150
|
+
systemInstanceId: crypto.randomUUID(),
|
|
151
|
+
},
|
|
152
|
+
}))
|
|
153
|
+
|
|
154
|
+
self.addEventListener('message', (event) => {
|
|
155
|
+
if (event.data?.type !== 'xl1-current-block') return
|
|
156
|
+
void systemHost.dispatch(event, async (session) => {
|
|
157
|
+
const actor = session.actors.find(actor => actor instanceof Xl1BrowserSystemActor)
|
|
158
|
+
if (actor === undefined) throw new Error('XL1 service-worker actor was not created')
|
|
159
|
+
const gateway = await actor.getGateway()
|
|
160
|
+
event.source?.postMessage({
|
|
161
|
+
blockNumber: await gateway.connection.viewer?.block.currentBlockNumber(),
|
|
162
|
+
type: 'xl1-current-block-result',
|
|
163
|
+
})
|
|
164
|
+
})
|
|
165
|
+
})
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Register the module service worker from a page and communicate with its active
|
|
169
|
+
instance. Browser termination discards resident memory; the next event launches
|
|
170
|
+
the same plan with a new `systemInstanceId`.
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
import serviceWorkerUrl from './xl1.service-worker.ts?worker&url'
|
|
174
|
+
|
|
175
|
+
const registration = await navigator.serviceWorker.register(
|
|
176
|
+
serviceWorkerUrl,
|
|
177
|
+
{ type: 'module' },
|
|
178
|
+
)
|
|
179
|
+
registration.active?.postMessage({ type: 'xl1-current-block' })
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Timers are not durable service-worker triggers. Use browser events, alarms, or
|
|
183
|
+
sync APIs, and keep durable state in providers rather than worker globals. See
|
|
184
|
+
the executable [service worker](https://github.com/XYOracleNetwork/xl1-protocol/blob/v/5/packages/browser-system/examples/xl1.service-worker.ts)
|
|
185
|
+
and [registration client](https://github.com/XYOracleNetwork/xl1-protocol/blob/v/5/packages/browser-system/examples/serviceWorker.ts).
|
|
186
|
+
|
|
187
|
+
## Browser plugin or extension
|
|
188
|
+
|
|
189
|
+
The extension background service worker owns the XL1 locator. Popups, side
|
|
190
|
+
panels, and content scripts attach through an authorized extension port; they do
|
|
191
|
+
not resolve a second provider system.
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
import { bindExtensionRuntimeBrowserSystemHost } from '@ariestools/browser-kit-plugin'
|
|
195
|
+
import { ServiceWorkerSystemHost } from '@ariestools/browser-kit-service-worker'
|
|
196
|
+
import type { XyoGateway } from '@xyo-network/xl1-sdk'
|
|
197
|
+
import { XyoGatewayMoniker } from '@xyo-network/xl1-sdk'
|
|
198
|
+
import { launchXl1BrowserSystem } from '@xyo-network/xl1-browser-system'
|
|
199
|
+
|
|
200
|
+
const systemHost = new ServiceWorkerSystemHost(async () =>
|
|
201
|
+
await launchXl1BrowserSystem({
|
|
202
|
+
config,
|
|
203
|
+
host: 'extension-background',
|
|
204
|
+
identity: {
|
|
205
|
+
planId: 'my-extension-xl1:v1',
|
|
206
|
+
systemInstanceId: crypto.randomUUID(),
|
|
207
|
+
},
|
|
208
|
+
}))
|
|
209
|
+
|
|
210
|
+
bindExtensionRuntimeBrowserSystemHost(chrome.runtime, {
|
|
211
|
+
authorize: port =>
|
|
212
|
+
(port.sender as { id?: string } | undefined)?.id === chrome.runtime.id,
|
|
213
|
+
channelName: 'my-extension-xl1',
|
|
214
|
+
getSession: async () => await systemHost.session(),
|
|
215
|
+
handlers: {
|
|
216
|
+
[XyoGatewayMoniker]: {
|
|
217
|
+
currentBlockNumber: async ({ instance }) =>
|
|
218
|
+
await (instance as XyoGateway).connection.viewer?.block.currentBlockNumber(),
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
onError: error => console.error('XL1 extension system failed', error),
|
|
222
|
+
})
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
The required `authorize` callback is application policy. `planId` expresses
|
|
226
|
+
compatibility and `systemInstanceId` detects stale clients; neither value
|
|
227
|
+
authenticates a caller. Only explicitly registered provider operations cross
|
|
228
|
+
the port.
|
|
229
|
+
|
|
230
|
+
The complete Manifest V3 fixture includes both sides of the connection:
|
|
231
|
+
|
|
232
|
+
- [background owner](https://github.com/XYOracleNetwork/xl1-protocol/blob/v/5/packages/browser-system/examples/extension/service-worker.ts)
|
|
233
|
+
- [attached extension page](https://github.com/XYOracleNetwork/xl1-protocol/blob/v/5/packages/browser-system/examples/extension/client.ts)
|
|
234
|
+
- [manifest](https://github.com/XYOracleNetwork/xl1-protocol/blob/v/5/packages/browser-system/examples/extension/public/manifest.json)
|
|
235
|
+
|
|
236
|
+
Custody, permissions, storage, operation schemas, and sender policy remain
|
|
237
|
+
application concerns.
|
|
238
|
+
|
|
239
|
+
## Run the real-browser examples
|
|
240
|
+
|
|
241
|
+
The repository includes a production-minified Vite build and Playwright suite.
|
|
242
|
+
It performs a typed block-number read in every realm and forces Chromium to
|
|
243
|
+
terminate and reconstruct both the standard and extension service workers:
|
|
26
244
|
|
|
27
|
-
|
|
245
|
+
```sh
|
|
246
|
+
pnpm --filter @xyo-network/xl1-browser-system test:e2e
|
|
28
247
|
```
|
|
29
248
|
|
|
30
249
|
Browser-kit owns realm lifecycle and transport. This package owns only the XL1
|
|
31
250
|
provider catalog, locator provisioning, standard actor, and XL1 configuration
|
|
32
|
-
helpers.
|
|
33
|
-
remain application concerns.
|
|
251
|
+
helpers.
|
|
@@ -10,8 +10,11 @@ export interface CreateXl1RestBrowserSystemConfigOptions {
|
|
|
10
10
|
readonly dataLakeEndpoint?: string;
|
|
11
11
|
readonly endpoint: string;
|
|
12
12
|
readonly host?: string;
|
|
13
|
+
readonly layout?: Xl1RestEndpointLayout;
|
|
13
14
|
readonly primeCaches?: PrimeCachesMode;
|
|
14
15
|
}
|
|
16
|
+
/** How the REST gateway's finalized, chain-state, and index URLs are derived from its endpoint. */
|
|
17
|
+
export type Xl1RestEndpointLayout = 'path' | 'subdomain';
|
|
15
18
|
/** Parses XL1 locator fields and browser actor selections without importing code from config. */
|
|
16
19
|
export declare function parseXl1BrowserSystemConfig(input: unknown): Xl1BrowserSystemConfig;
|
|
17
20
|
/** Projects the XL1 config onto the neutral fields browser-kit compiles. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Xl1BrowserConfig.d.ts","sourceRoot":"","sources":["../../src/Xl1BrowserConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,yBAAyB,CAAA;AAEhC,OAAO,KAAK,EAEV,aAAa,EACb,eAAe,
|
|
1
|
+
{"version":3,"file":"Xl1BrowserConfig.d.ts","sourceRoot":"","sources":["../../src/Xl1BrowserConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,yBAAyB,CAAA;AAEhC,OAAO,KAAK,EAEV,aAAa,EACb,eAAe,EAGhB,MAAM,sBAAsB,CAAA;AAyB7B,iEAAiE;AACjE,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IAC3D,QAAQ,CAAC,MAAM,EAAE,SAAS,qBAAqB,EAAE,CAAA;CAClD;AAED,yEAAyE;AACzE,MAAM,WAAW,uCAAuC;IACtD,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAA;IAClD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,qBAAqB,CAAA;IACvC,QAAQ,CAAC,WAAW,CAAC,EAAE,eAAe,CAAA;CACvC;AAED,mGAAmG;AACnG,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,WAAW,CAAA;AAExD,iGAAiG;AACjG,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,sBAAsB,CAWlF;AAED,4EAA4E;AAC5E,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,sBAAsB,GAC7B,mBAAmB,CAMrB;AAED,iGAAiG;AACjG,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,uCAAuC,GAC/C,sBAAsB,CA0CxB"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { BrowserSystemProvisioner } from '@ariestools/browser-kit';
|
|
2
2
|
import type { CreatableProviderContext, ProviderDescriptor as Xl1ProviderDescriptor, ProviderFactoryLocatorInstance } from '@xyo-network/xl1-sdk';
|
|
3
3
|
import type { Xl1BrowserSystemConfig } from './Xl1BrowserConfig.ts';
|
|
4
|
+
/** Stable browser-provider identifier retained across production minification. */
|
|
5
|
+
export declare const SimpleXyoConnectionViewerProviderId = "SimpleXyoConnectionViewer";
|
|
6
|
+
/** Stable browser-provider identifier retained across production minification. */
|
|
7
|
+
export declare const SimpleXyoGatewayProviderId = "SimpleXyoGateway";
|
|
4
8
|
/** Browser-kit plan metadata retaining the XL1 provider class used by the provisioner. */
|
|
5
9
|
export interface Xl1BrowserProviderDeclaration {
|
|
6
10
|
readonly connectionTypes: readonly string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Xl1BrowserProvider.d.ts","sourceRoot":"","sources":["../../src/Xl1BrowserProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAGvE,OAAO,KAAK,EAEV,wBAAwB,EAGxB,kBAAkB,IAAI,qBAAqB,EAC3C,8BAA8B,EAC/B,MAAM,sBAAsB,CAAA;AAU7B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAEnE,0FAA0F;AAC1F,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3C,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,QAAQ,CAAC,GAAG,EAAE,qBAAqB,CAAA;CACpC;AAED,qFAAqF;AACrF,MAAM,MAAM,gCAAgC,GAAG,IAAI,CACjD,wBAAwB,EACxB,QAAQ,GAAG,SAAS,CACrB,CAAA;AAED,8DAA8D;AAC9D,MAAM,WAAW,wCAAwC;IACvD,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAA;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,gCAAgC,CAAA;CACpD;AAED,gFAAgF;AAChF,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,qBAAqB,GAChC,6BAA6B,CAQ/B;AAED,kFAAkF;AAClF,wBAAgB,4BAA4B,IAAI,qBAAqB,EAAE,CAMtE;AAED,+DAA+D;AAC/D,wBAAgB,8BAA8B,CAC5C,UAAU,GAAE,SAAS,qBAAqB,EAAmC,GAC5E,6BAA6B,EAAE,CAEjC;AAED,sFAAsF;AACtF,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,wCAAwC,GAChD,wBAAwB,CAAC,8BAA8B,CAAC,CA8D1D"}
|
|
1
|
+
{"version":3,"file":"Xl1BrowserProvider.d.ts","sourceRoot":"","sources":["../../src/Xl1BrowserProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAGvE,OAAO,KAAK,EAEV,wBAAwB,EAGxB,kBAAkB,IAAI,qBAAqB,EAC3C,8BAA8B,EAC/B,MAAM,sBAAsB,CAAA;AAU7B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAEnE,kFAAkF;AAClF,eAAO,MAAM,mCAAmC,8BAA8B,CAAA;AAC9E,kFAAkF;AAClF,eAAO,MAAM,0BAA0B,qBAAqB,CAAA;AAE5D,0FAA0F;AAC1F,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3C,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,QAAQ,CAAC,GAAG,EAAE,qBAAqB,CAAA;CACpC;AAED,qFAAqF;AACrF,MAAM,MAAM,gCAAgC,GAAG,IAAI,CACjD,wBAAwB,EACxB,QAAQ,GAAG,SAAS,CACrB,CAAA;AAED,8DAA8D;AAC9D,MAAM,WAAW,wCAAwC;IACvD,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAA;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,gCAAgC,CAAA;CACpD;AAED,gFAAgF;AAChF,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,qBAAqB,GAChC,6BAA6B,CAQ/B;AAED,kFAAkF;AAClF,wBAAgB,4BAA4B,IAAI,qBAAqB,EAAE,CAMtE;AAED,+DAA+D;AAC/D,wBAAgB,8BAA8B,CAC5C,UAAU,GAAE,SAAS,qBAAqB,EAAmC,GAC5E,6BAA6B,EAAE,CAEjC;AAED,sFAAsF;AACtF,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,wCAAwC,GAChD,wBAAwB,CAAC,8BAA8B,CAAC,CA8D1D"}
|
package/dist/browser/index.mjs
CHANGED
|
@@ -14,131 +14,10 @@ import {
|
|
|
14
14
|
parseLocatorConfigFields,
|
|
15
15
|
restConnectionFromS3Bucket,
|
|
16
16
|
restGatewayConfigFromEndpoint,
|
|
17
|
-
SimpleXyoConnectionViewer,
|
|
18
|
-
SimpleXyoGateway,
|
|
19
17
|
XyoConnectionMoniker,
|
|
20
18
|
XyoGatewayMoniker as XyoGatewayMoniker2
|
|
21
19
|
} from "@xyo-network/xl1-sdk";
|
|
22
20
|
|
|
23
|
-
// src/Xl1BrowserSystemActor.ts
|
|
24
|
-
import { ProviderActor } from "@ariestools/actor";
|
|
25
|
-
import { BrowserActorCatalog as BrowserActorCatalogInstance } from "@ariestools/browser-kit";
|
|
26
|
-
import {
|
|
27
|
-
DataLakeViewerMoniker,
|
|
28
|
-
XyoGatewayMoniker
|
|
29
|
-
} from "@xyo-network/xl1-sdk";
|
|
30
|
-
var Xl1BrowserSystemActorType = "xl1-system";
|
|
31
|
-
var Xl1BrowserSystemWithDataLakeActorType = "xl1-system-with-data-lake";
|
|
32
|
-
var Xl1BrowserSystemActor = class extends ProviderActor {
|
|
33
|
-
/** Resolves the gateway owned by this actor's immutable provider system. */
|
|
34
|
-
async getGateway() {
|
|
35
|
-
if (this.status !== "started") {
|
|
36
|
-
throw new Error(`XL1 browser system actor is not running (status: ${this.status})`);
|
|
37
|
-
}
|
|
38
|
-
return await this.getProvider(XyoGatewayMoniker);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
var Xl1BrowserSystemActorDependencies = [XyoGatewayMoniker];
|
|
42
|
-
var Xl1BrowserSystemWithDataLakeActorDependencies = [
|
|
43
|
-
XyoGatewayMoniker,
|
|
44
|
-
DataLakeViewerMoniker
|
|
45
|
-
];
|
|
46
|
-
function createXl1BrowserActorCatalog() {
|
|
47
|
-
const catalog = new BrowserActorCatalogInstance();
|
|
48
|
-
const create = async (id, providerContext) => await Xl1BrowserSystemActor.create({
|
|
49
|
-
name: id,
|
|
50
|
-
providerContext
|
|
51
|
-
});
|
|
52
|
-
catalog.register({
|
|
53
|
-
create: async ({ id, providerContext }) => await create(
|
|
54
|
-
id,
|
|
55
|
-
providerContext
|
|
56
|
-
),
|
|
57
|
-
dependencies: Xl1BrowserSystemActorDependencies,
|
|
58
|
-
type: Xl1BrowserSystemActorType
|
|
59
|
-
});
|
|
60
|
-
catalog.register({
|
|
61
|
-
create: async ({ id, providerContext }) => await create(
|
|
62
|
-
id,
|
|
63
|
-
providerContext
|
|
64
|
-
),
|
|
65
|
-
dependencies: Xl1BrowserSystemWithDataLakeActorDependencies,
|
|
66
|
-
type: Xl1BrowserSystemWithDataLakeActorType
|
|
67
|
-
});
|
|
68
|
-
return catalog;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// src/Xl1BrowserConfig.ts
|
|
72
|
-
function parseXl1BrowserSystemConfig(input) {
|
|
73
|
-
const locatorConfig = parseLocatorConfigFields(input);
|
|
74
|
-
const browserConfig = parseBrowserSystemConfig({
|
|
75
|
-
actors: isRecord(input) ? input["actors"] : void 0,
|
|
76
|
-
connections: locatorConfig.connections,
|
|
77
|
-
providerBindings: toBrowserProviderBindings(locatorConfig.providerBindings)
|
|
78
|
-
});
|
|
79
|
-
return Object.freeze({
|
|
80
|
-
...locatorConfig,
|
|
81
|
-
actors: Object.freeze([...browserConfig.actors ?? []])
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
function toBrowserSystemConfig(config) {
|
|
85
|
-
return {
|
|
86
|
-
actors: config.actors,
|
|
87
|
-
connections: config.connections,
|
|
88
|
-
providerBindings: toBrowserProviderBindings(config.providerBindings)
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
function createXl1RestBrowserSystemConfig(options) {
|
|
92
|
-
const buckets = restGatewayConfigFromEndpoint(options.endpoint);
|
|
93
|
-
const finalized = buckets.finalized;
|
|
94
|
-
if (finalized === void 0) throw new Error("XL1 REST gateway has no finalized bucket");
|
|
95
|
-
const connections = {
|
|
96
|
-
"rest-chain-state": restConnectionFromS3Bucket(buckets.chainState ?? finalized),
|
|
97
|
-
"rest-finalized": restConnectionFromS3Bucket(finalized),
|
|
98
|
-
"rest-index": restConnectionFromS3Bucket(buckets.index ?? finalized)
|
|
99
|
-
};
|
|
100
|
-
const providerBindings = {
|
|
101
|
-
[BlockViewerMoniker]: { connection: "rest-finalized" },
|
|
102
|
-
[ChainContractViewerMoniker]: { connection: "rest-chain-state" },
|
|
103
|
-
[ChainStateViewerMoniker]: { connection: "rest-chain-state" },
|
|
104
|
-
[FinalizationViewerMoniker]: { connection: "rest-finalized" },
|
|
105
|
-
[IndexViewerMoniker]: { connection: "rest-index" },
|
|
106
|
-
[XyoConnectionMoniker]: { provider: SimpleXyoConnectionViewer.name },
|
|
107
|
-
[XyoGatewayMoniker2]: { provider: SimpleXyoGateway.name }
|
|
108
|
-
};
|
|
109
|
-
if (options.dataLakeEndpoint !== void 0) {
|
|
110
|
-
connections["rest-data-lake"] = {
|
|
111
|
-
baseUrl: options.dataLakeEndpoint,
|
|
112
|
-
type: "rest"
|
|
113
|
-
};
|
|
114
|
-
providerBindings[DataLakeViewerMoniker2] = { connection: "rest-data-lake" };
|
|
115
|
-
}
|
|
116
|
-
if (options.primeCaches !== void 0) {
|
|
117
|
-
providerBindings[NetworkStakeStepRewardsByPositionViewerMoniker] = { primeCaches: options.primeCaches };
|
|
118
|
-
}
|
|
119
|
-
return parseXl1BrowserSystemConfig({
|
|
120
|
-
actors: options.actors ?? [{
|
|
121
|
-
host: options.host,
|
|
122
|
-
type: options.dataLakeEndpoint === void 0 ? Xl1BrowserSystemActorType : Xl1BrowserSystemWithDataLakeActorType
|
|
123
|
-
}],
|
|
124
|
-
connections,
|
|
125
|
-
providerBindings
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
function toBrowserProviderBindings(bindings) {
|
|
129
|
-
return Object.fromEntries(Object.entries(bindings).map(([moniker, binding]) => [
|
|
130
|
-
moniker,
|
|
131
|
-
binding === void 0 ? {} : {
|
|
132
|
-
connection: binding.connection,
|
|
133
|
-
options: binding.options,
|
|
134
|
-
provider: binding.provider
|
|
135
|
-
}
|
|
136
|
-
]));
|
|
137
|
-
}
|
|
138
|
-
function isRecord(value) {
|
|
139
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
21
|
// src/Xl1BrowserProvider.ts
|
|
143
22
|
import { stopOrShutdown } from "@ariestools/actor";
|
|
144
23
|
import { createResolvedBrowserProviderPlan } from "@ariestools/browser-kit";
|
|
@@ -148,9 +27,11 @@ import {
|
|
|
148
27
|
compileLocatorConfig,
|
|
149
28
|
providerCandidateFromClass,
|
|
150
29
|
ProviderFactoryLocator,
|
|
151
|
-
SimpleXyoConnectionViewer
|
|
152
|
-
SimpleXyoGateway
|
|
30
|
+
SimpleXyoConnectionViewer,
|
|
31
|
+
SimpleXyoGateway
|
|
153
32
|
} from "@xyo-network/xl1-sdk";
|
|
33
|
+
var SimpleXyoConnectionViewerProviderId = "SimpleXyoConnectionViewer";
|
|
34
|
+
var SimpleXyoGatewayProviderId = "SimpleXyoGateway";
|
|
154
35
|
function xl1BrowserProviderDeclaration(descriptor) {
|
|
155
36
|
return Object.freeze({
|
|
156
37
|
connectionTypes: Object.freeze([...descriptor.connectionTypes]),
|
|
@@ -163,8 +44,8 @@ function xl1BrowserProviderDeclaration(descriptor) {
|
|
|
163
44
|
function xl1BrowserProviderCandidates() {
|
|
164
45
|
return [
|
|
165
46
|
...allProviderCandidates(),
|
|
166
|
-
providerCandidateFromClass(
|
|
167
|
-
providerCandidateFromClass(
|
|
47
|
+
providerCandidateFromClass(SimpleXyoConnectionViewer, SimpleXyoConnectionViewerProviderId),
|
|
48
|
+
providerCandidateFromClass(SimpleXyoGateway, SimpleXyoGatewayProviderId)
|
|
168
49
|
];
|
|
169
50
|
}
|
|
170
51
|
function xl1BrowserProviderDeclarations(candidates = xl1BrowserProviderCandidates()) {
|
|
@@ -265,6 +146,133 @@ function isCreatableProviderInstance(value) {
|
|
|
265
146
|
return typeof value === "object" && value !== null && "stop" in value && typeof value.stop === "function";
|
|
266
147
|
}
|
|
267
148
|
|
|
149
|
+
// src/Xl1BrowserSystemActor.ts
|
|
150
|
+
import { ProviderActor } from "@ariestools/actor";
|
|
151
|
+
import { BrowserActorCatalog as BrowserActorCatalogInstance } from "@ariestools/browser-kit";
|
|
152
|
+
import {
|
|
153
|
+
DataLakeViewerMoniker,
|
|
154
|
+
XyoGatewayMoniker
|
|
155
|
+
} from "@xyo-network/xl1-sdk";
|
|
156
|
+
var Xl1BrowserSystemActorType = "xl1-system";
|
|
157
|
+
var Xl1BrowserSystemWithDataLakeActorType = "xl1-system-with-data-lake";
|
|
158
|
+
var Xl1BrowserSystemActor = class extends ProviderActor {
|
|
159
|
+
/** Resolves the gateway owned by this actor's immutable provider system. */
|
|
160
|
+
async getGateway() {
|
|
161
|
+
if (this.status !== "started") {
|
|
162
|
+
throw new Error(`XL1 browser system actor is not running (status: ${this.status})`);
|
|
163
|
+
}
|
|
164
|
+
return await this.getProvider(XyoGatewayMoniker);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
var Xl1BrowserSystemActorDependencies = [XyoGatewayMoniker];
|
|
168
|
+
var Xl1BrowserSystemWithDataLakeActorDependencies = [
|
|
169
|
+
XyoGatewayMoniker,
|
|
170
|
+
DataLakeViewerMoniker
|
|
171
|
+
];
|
|
172
|
+
function createXl1BrowserActorCatalog() {
|
|
173
|
+
const catalog = new BrowserActorCatalogInstance();
|
|
174
|
+
const create = async (id, providerContext) => await Xl1BrowserSystemActor.create({
|
|
175
|
+
name: id,
|
|
176
|
+
providerContext
|
|
177
|
+
});
|
|
178
|
+
catalog.register({
|
|
179
|
+
create: async ({ id, providerContext }) => await create(
|
|
180
|
+
id,
|
|
181
|
+
providerContext
|
|
182
|
+
),
|
|
183
|
+
dependencies: Xl1BrowserSystemActorDependencies,
|
|
184
|
+
type: Xl1BrowserSystemActorType
|
|
185
|
+
});
|
|
186
|
+
catalog.register({
|
|
187
|
+
create: async ({ id, providerContext }) => await create(
|
|
188
|
+
id,
|
|
189
|
+
providerContext
|
|
190
|
+
),
|
|
191
|
+
dependencies: Xl1BrowserSystemWithDataLakeActorDependencies,
|
|
192
|
+
type: Xl1BrowserSystemWithDataLakeActorType
|
|
193
|
+
});
|
|
194
|
+
return catalog;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// src/Xl1BrowserConfig.ts
|
|
198
|
+
function parseXl1BrowserSystemConfig(input) {
|
|
199
|
+
const locatorConfig = parseLocatorConfigFields(input);
|
|
200
|
+
const browserConfig = parseBrowserSystemConfig({
|
|
201
|
+
actors: isRecord(input) ? input["actors"] : void 0,
|
|
202
|
+
connections: locatorConfig.connections,
|
|
203
|
+
providerBindings: toBrowserProviderBindings(locatorConfig.providerBindings)
|
|
204
|
+
});
|
|
205
|
+
return Object.freeze({
|
|
206
|
+
...locatorConfig,
|
|
207
|
+
actors: Object.freeze([...browserConfig.actors ?? []])
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
function toBrowserSystemConfig(config) {
|
|
211
|
+
return {
|
|
212
|
+
actors: config.actors,
|
|
213
|
+
connections: config.connections,
|
|
214
|
+
providerBindings: toBrowserProviderBindings(config.providerBindings)
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function createXl1RestBrowserSystemConfig(options) {
|
|
218
|
+
const buckets = options.layout === "path" ? restGatewayConfigFromPathEndpoint(options.endpoint) : restGatewayConfigFromEndpoint(options.endpoint);
|
|
219
|
+
const finalized = buckets.finalized;
|
|
220
|
+
if (finalized === void 0) throw new Error("XL1 REST gateway has no finalized bucket");
|
|
221
|
+
const connections = {
|
|
222
|
+
"rest-chain-state": restConnectionFromS3Bucket(buckets.chainState ?? finalized),
|
|
223
|
+
"rest-finalized": restConnectionFromS3Bucket(finalized),
|
|
224
|
+
"rest-index": restConnectionFromS3Bucket(buckets.index ?? finalized)
|
|
225
|
+
};
|
|
226
|
+
const providerBindings = {
|
|
227
|
+
[BlockViewerMoniker]: { connection: "rest-finalized" },
|
|
228
|
+
[ChainContractViewerMoniker]: { connection: "rest-chain-state" },
|
|
229
|
+
[ChainStateViewerMoniker]: { connection: "rest-chain-state" },
|
|
230
|
+
[FinalizationViewerMoniker]: { connection: "rest-finalized" },
|
|
231
|
+
[IndexViewerMoniker]: { connection: "rest-index" },
|
|
232
|
+
[XyoConnectionMoniker]: { provider: SimpleXyoConnectionViewerProviderId },
|
|
233
|
+
[XyoGatewayMoniker2]: { provider: SimpleXyoGatewayProviderId }
|
|
234
|
+
};
|
|
235
|
+
if (options.dataLakeEndpoint !== void 0) {
|
|
236
|
+
connections["rest-data-lake"] = {
|
|
237
|
+
baseUrl: options.dataLakeEndpoint,
|
|
238
|
+
type: "rest"
|
|
239
|
+
};
|
|
240
|
+
providerBindings[DataLakeViewerMoniker2] = { connection: "rest-data-lake" };
|
|
241
|
+
}
|
|
242
|
+
if (options.primeCaches !== void 0) {
|
|
243
|
+
providerBindings[NetworkStakeStepRewardsByPositionViewerMoniker] = { primeCaches: options.primeCaches };
|
|
244
|
+
}
|
|
245
|
+
return parseXl1BrowserSystemConfig({
|
|
246
|
+
actors: options.actors ?? [{
|
|
247
|
+
host: options.host,
|
|
248
|
+
type: options.dataLakeEndpoint === void 0 ? Xl1BrowserSystemActorType : Xl1BrowserSystemWithDataLakeActorType
|
|
249
|
+
}],
|
|
250
|
+
connections,
|
|
251
|
+
providerBindings
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
function restGatewayConfigFromPathEndpoint(endpoint) {
|
|
255
|
+
const baseUrl = endpoint.endsWith("/") ? endpoint.slice(0, -1) : endpoint;
|
|
256
|
+
return {
|
|
257
|
+
chainState: { readUrl: `${baseUrl}/state` },
|
|
258
|
+
finalized: { readUrl: `${baseUrl}/blocks` },
|
|
259
|
+
index: { readUrl: `${baseUrl}/indexes` }
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
function toBrowserProviderBindings(bindings) {
|
|
263
|
+
return Object.fromEntries(Object.entries(bindings).map(([moniker, binding]) => [
|
|
264
|
+
moniker,
|
|
265
|
+
binding === void 0 ? {} : {
|
|
266
|
+
connection: binding.connection,
|
|
267
|
+
options: binding.options,
|
|
268
|
+
provider: binding.provider
|
|
269
|
+
}
|
|
270
|
+
]));
|
|
271
|
+
}
|
|
272
|
+
function isRecord(value) {
|
|
273
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
274
|
+
}
|
|
275
|
+
|
|
268
276
|
// src/launchXl1BrowserSystem.ts
|
|
269
277
|
async function launchXl1BrowserSystem(options) {
|
|
270
278
|
const config = parseXl1BrowserSystemConfig(options.config);
|
|
@@ -284,6 +292,8 @@ async function launchXl1BrowserSystem(options) {
|
|
|
284
292
|
});
|
|
285
293
|
}
|
|
286
294
|
export {
|
|
295
|
+
SimpleXyoConnectionViewerProviderId,
|
|
296
|
+
SimpleXyoGatewayProviderId,
|
|
287
297
|
Xl1BrowserSystemActor,
|
|
288
298
|
Xl1BrowserSystemActorDependencies,
|
|
289
299
|
Xl1BrowserSystemActorType,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../src/launchXl1BrowserSystem.ts", "../../src/Xl1BrowserConfig.ts", "../../src/
|
|
4
|
-
"sourcesContent": ["import type {\n BrowserActor,\n BrowserActorCatalog,\n BrowserProviderDescriptor,\n BrowserSystemIdentity,\n BrowserSystemSession,\n} from '@ariestools/browser-kit'\nimport { launchBrowserSystem } from '@ariestools/browser-kit'\nimport type {\n ProviderDescriptor as Xl1ProviderDescriptor,\n ProviderFactoryLocatorInstance,\n} from '@xyo-network/xl1-sdk'\n\nimport {\n parseXl1BrowserSystemConfig,\n toBrowserSystemConfig,\n} from './Xl1BrowserConfig.ts'\nimport {\n createXl1BrowserSystemProvisioner,\n xl1BrowserProviderDeclarations,\n type Xl1BrowserProviderRuntimeContext,\n} from './Xl1BrowserProvider.ts'\nimport { createXl1BrowserActorCatalog } from './Xl1BrowserSystemActor.ts'\n\n/** Inputs for launching one owner-resolved XL1 browser provider system. */\nexport interface LaunchXl1BrowserSystemOptions<TActor extends BrowserActor = BrowserActor> {\n readonly actorCatalog?: BrowserActorCatalog<TActor, ProviderFactoryLocatorInstance>\n readonly config: unknown\n readonly context?: Xl1BrowserProviderRuntimeContext\n readonly host?: string\n readonly identity?: BrowserSystemIdentity\n readonly providerCandidates?: readonly Xl1ProviderDescriptor[]\n readonly readyTimeoutMs?: number\n}\n\n/** Parses, resolves, provisions, and starts one XL1 system from browser-safe config. */\nexport async function launchXl1BrowserSystem<TActor extends BrowserActor = BrowserActor>(\n options: LaunchXl1BrowserSystemOptions<TActor>,\n): Promise<BrowserSystemSession<TActor, ProviderFactoryLocatorInstance>> {\n const config = parseXl1BrowserSystemConfig(options.config)\n const actorCatalog = options.actorCatalog\n ?? createXl1BrowserActorCatalog() as BrowserActorCatalog<TActor, ProviderFactoryLocatorInstance>\n const providerDescriptors = xl1BrowserProviderDeclarations(options.providerCandidates)\n return await launchBrowserSystem({\n actorCatalog,\n config: toBrowserSystemConfig(config),\n host: options.host,\n identity: options.identity,\n providerDescriptors: providerDescriptors as unknown as BrowserProviderDescriptor[],\n provision: createXl1BrowserSystemProvisioner({\n config,\n context: options.context,\n }),\n readyTimeoutMs: options.readyTimeoutMs,\n })\n}\n", "import type {\n BrowserActorSelection,\n BrowserSystemConfig,\n} from '@ariestools/browser-kit'\nimport { parseBrowserSystemConfig } from '@ariestools/browser-kit'\nimport type {\n ConnectionsConfig,\n LocatorConfig,\n PrimeCachesMode,\n ProviderBindingsConfig,\n} from '@xyo-network/xl1-sdk'\nimport {\n BlockViewerMoniker,\n ChainContractViewerMoniker,\n ChainStateViewerMoniker,\n DataLakeViewerMoniker,\n FinalizationViewerMoniker,\n IndexViewerMoniker,\n NetworkStakeStepRewardsByPositionViewerMoniker,\n parseLocatorConfigFields,\n restConnectionFromS3Bucket,\n restGatewayConfigFromEndpoint,\n SimpleXyoConnectionViewer,\n SimpleXyoGateway,\n XyoConnectionMoniker,\n XyoGatewayMoniker,\n} from '@xyo-network/xl1-sdk'\n\nimport {\n Xl1BrowserSystemActorType,\n Xl1BrowserSystemWithDataLakeActorType,\n} from './Xl1BrowserSystemActor.ts'\n\n/** Authored XL1 locator fields plus browser actor selections. */\nexport interface Xl1BrowserSystemConfig extends LocatorConfig {\n readonly actors: readonly BrowserActorSelection[]\n}\n\n/** Options for the standard read-only REST-backed XL1 browser system. */\nexport interface CreateXl1RestBrowserSystemConfigOptions {\n readonly actors?: readonly BrowserActorSelection[]\n readonly dataLakeEndpoint?: string\n readonly endpoint: string\n readonly host?: string\n readonly primeCaches?: PrimeCachesMode\n}\n\n/** Parses XL1 locator fields and browser actor selections without importing code from config. */\nexport function parseXl1BrowserSystemConfig(input: unknown): Xl1BrowserSystemConfig {\n const locatorConfig = parseLocatorConfigFields(input)\n const browserConfig = parseBrowserSystemConfig({\n actors: isRecord(input) ? input['actors'] : undefined,\n connections: locatorConfig.connections,\n providerBindings: toBrowserProviderBindings(locatorConfig.providerBindings),\n })\n return Object.freeze({\n ...locatorConfig,\n actors: Object.freeze([...(browserConfig.actors ?? [])]),\n })\n}\n\n/** Projects the XL1 config onto the neutral fields browser-kit compiles. */\nexport function toBrowserSystemConfig(\n config: Xl1BrowserSystemConfig,\n): BrowserSystemConfig {\n return {\n actors: config.actors,\n connections: config.connections,\n providerBindings: toBrowserProviderBindings(config.providerBindings),\n }\n}\n\n/** Creates explicit REST connections and provider bindings for a read-only XL1 gateway actor. */\nexport function createXl1RestBrowserSystemConfig(\n options: CreateXl1RestBrowserSystemConfigOptions,\n): Xl1BrowserSystemConfig {\n const buckets = restGatewayConfigFromEndpoint(options.endpoint)\n const finalized = buckets.finalized\n if (finalized === undefined) throw new Error('XL1 REST gateway has no finalized bucket')\n\n const connections: ConnectionsConfig = {\n 'rest-chain-state': restConnectionFromS3Bucket(buckets.chainState ?? finalized),\n 'rest-finalized': restConnectionFromS3Bucket(finalized),\n 'rest-index': restConnectionFromS3Bucket(buckets.index ?? finalized),\n }\n const providerBindings: ProviderBindingsConfig = {\n [BlockViewerMoniker]: { connection: 'rest-finalized' },\n [ChainContractViewerMoniker]: { connection: 'rest-chain-state' },\n [ChainStateViewerMoniker]: { connection: 'rest-chain-state' },\n [FinalizationViewerMoniker]: { connection: 'rest-finalized' },\n [IndexViewerMoniker]: { connection: 'rest-index' },\n [XyoConnectionMoniker]: { provider: SimpleXyoConnectionViewer.name },\n [XyoGatewayMoniker]: { provider: SimpleXyoGateway.name },\n }\n if (options.dataLakeEndpoint !== undefined) {\n connections['rest-data-lake'] = {\n baseUrl: options.dataLakeEndpoint,\n type: 'rest',\n }\n providerBindings[DataLakeViewerMoniker] = { connection: 'rest-data-lake' }\n }\n if (options.primeCaches !== undefined) {\n providerBindings[NetworkStakeStepRewardsByPositionViewerMoniker] = { primeCaches: options.primeCaches }\n }\n\n return parseXl1BrowserSystemConfig({\n actors: options.actors ?? [{\n host: options.host,\n type: options.dataLakeEndpoint === undefined\n ? Xl1BrowserSystemActorType\n : Xl1BrowserSystemWithDataLakeActorType,\n }],\n connections,\n providerBindings,\n })\n}\n\nfunction toBrowserProviderBindings(\n bindings: ProviderBindingsConfig,\n): NonNullable<BrowserSystemConfig['providerBindings']> {\n return Object.fromEntries(Object.entries(bindings).map(([moniker, binding]) => [\n moniker,\n binding === undefined\n ? {}\n : {\n connection: binding.connection,\n options: binding.options,\n provider: binding.provider,\n },\n ]))\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n", "import type {\n ProviderActorContext,\n ProviderActorParams,\n} from '@ariestools/actor'\nimport { ProviderActor } from '@ariestools/actor'\nimport type {\n BrowserActor,\n ResolvedBrowserProviderPlan,\n ResolvedBrowserSystemConfig,\n} from '@ariestools/browser-kit'\nimport { BrowserActorCatalog as BrowserActorCatalogInstance } from '@ariestools/browser-kit'\nimport type { CreatableName } from '@ariestools/sdk'\nimport type {\n ProviderFactoryLocatorInstance,\n XyoGateway,\n} from '@xyo-network/xl1-sdk'\nimport {\n DataLakeViewerMoniker,\n XyoGatewayMoniker,\n} from '@xyo-network/xl1-sdk'\n\nexport const Xl1BrowserSystemActorType = 'xl1-system' as const\nexport const Xl1BrowserSystemWithDataLakeActorType = 'xl1-system-with-data-lake' as const\n\nexport interface Xl1BrowserSystemActorParams extends ProviderActorParams<\n ProviderFactoryLocatorInstance,\n ResolvedBrowserSystemConfig,\n unknown,\n ResolvedBrowserProviderPlan\n> {}\n\n/** Resident actor representing one configured XL1 gateway system. */\nexport class Xl1BrowserSystemActor extends ProviderActor<Xl1BrowserSystemActorParams> {\n /** Resolves the gateway owned by this actor's immutable provider system. */\n async getGateway(): Promise<XyoGateway> {\n if (this.status !== 'started') {\n throw new Error(`XL1 browser system actor is not running (status: ${this.status})`)\n }\n return await this.getProvider<XyoGateway>(XyoGatewayMoniker)\n }\n}\n\nexport const Xl1BrowserSystemActorDependencies = [XyoGatewayMoniker] as const\nexport const Xl1BrowserSystemWithDataLakeActorDependencies = [\n XyoGatewayMoniker,\n DataLakeViewerMoniker,\n] as const\n\n/** Creates the default actor catalog and optionally installs application actors. */\nexport function createXl1BrowserActorCatalog() {\n const catalog = new BrowserActorCatalogInstance<BrowserActor, ProviderFactoryLocatorInstance>()\n const create = async (\n id: string,\n providerContext: ProviderActorContext<\n ProviderFactoryLocatorInstance,\n ResolvedBrowserSystemConfig,\n unknown,\n ResolvedBrowserProviderPlan\n >,\n ) => await Xl1BrowserSystemActor.create({\n name: id as CreatableName,\n providerContext,\n })\n catalog.register({\n create: async ({ id, providerContext }) => await create(\n id,\n providerContext as ProviderActorContext<\n ProviderFactoryLocatorInstance,\n ResolvedBrowserSystemConfig,\n unknown,\n ResolvedBrowserProviderPlan\n >,\n ),\n dependencies: Xl1BrowserSystemActorDependencies,\n type: Xl1BrowserSystemActorType,\n })\n catalog.register({\n create: async ({ id, providerContext }) => await create(\n id,\n providerContext as ProviderActorContext<\n ProviderFactoryLocatorInstance,\n ResolvedBrowserSystemConfig,\n unknown,\n ResolvedBrowserProviderPlan\n >,\n ),\n dependencies: Xl1BrowserSystemWithDataLakeActorDependencies,\n type: Xl1BrowserSystemWithDataLakeActorType,\n })\n return catalog\n}\n", "import { stopOrShutdown } from '@ariestools/actor'\nimport type { BrowserSystemProvisioner } from '@ariestools/browser-kit'\nimport { createResolvedBrowserProviderPlan } from '@ariestools/browser-kit'\nimport { createResolvedProviderSystem } from '@ariestools/provider-model'\nimport type {\n ConnectionsConfig,\n CreatableProviderContext,\n CreatableProviderInstance,\n ProviderBindingsConfig,\n ProviderDescriptor as Xl1ProviderDescriptor,\n ProviderFactoryLocatorInstance,\n} from '@xyo-network/xl1-sdk'\nimport {\n allProviderCandidates,\n compileLocatorConfig,\n providerCandidateFromClass,\n ProviderFactoryLocator,\n SimpleXyoConnectionViewer,\n SimpleXyoGateway,\n} from '@xyo-network/xl1-sdk'\n\nimport type { Xl1BrowserSystemConfig } from './Xl1BrowserConfig.ts'\n\n/** Browser-kit plan metadata retaining the XL1 provider class used by the provisioner. */\nexport interface Xl1BrowserProviderDeclaration {\n readonly connectionTypes: readonly string[]\n readonly dependencies: readonly string[]\n readonly id: string\n readonly monikers: readonly string[]\n readonly xl1: Xl1ProviderDescriptor\n}\n\n/** Non-serializable XL1 runtime homes supplied by the realm that owns the system. */\nexport type Xl1BrowserProviderRuntimeContext = Omit<\n CreatableProviderContext,\n 'config' | 'locator'\n>\n\n/** Options captured by the XL1 browser-system provisioner. */\nexport interface CreateXl1BrowserSystemProvisionerOptions {\n readonly config: Xl1BrowserSystemConfig\n readonly context?: Xl1BrowserProviderRuntimeContext\n}\n\n/** Adapts one XL1 provider candidate into neutral browser-kit plan metadata. */\nexport function xl1BrowserProviderDeclaration(\n descriptor: Xl1ProviderDescriptor,\n): Xl1BrowserProviderDeclaration {\n return Object.freeze({\n connectionTypes: Object.freeze([...descriptor.connectionTypes]),\n dependencies: Object.freeze([...(descriptor.dependencies ?? [])]),\n id: descriptor.id,\n monikers: Object.freeze([...descriptor.satisfies]),\n xl1: descriptor,\n })\n}\n\n/** Returns the XL1 provider catalog available to browser-system configuration. */\nexport function xl1BrowserProviderCandidates(): Xl1ProviderDescriptor[] {\n return [\n ...allProviderCandidates(),\n providerCandidateFromClass(SimpleXyoConnectionViewer),\n providerCandidateFromClass(SimpleXyoGateway),\n ]\n}\n\n/** Adapts an XL1 provider catalog for browser-kit planning. */\nexport function xl1BrowserProviderDeclarations(\n candidates: readonly Xl1ProviderDescriptor[] = xl1BrowserProviderCandidates(),\n): Xl1BrowserProviderDeclaration[] {\n return candidates.map(xl1BrowserProviderDeclaration)\n}\n\n/** Creates the owner-realm provisioner that instantiates one resolved XL1 locator. */\nexport function createXl1BrowserSystemProvisioner(\n options: CreateXl1BrowserSystemProvisionerOptions,\n): BrowserSystemProvisioner<ProviderFactoryLocatorInstance> {\n return async (input) => {\n const providerBindings = mergeResolvedProviderBindings(\n options.config.providerBindings,\n input.compiled.config.providerBindings,\n )\n const locatorConfig = compileLocatorConfig({\n ...options.config,\n connections: input.compiled.config.connections as ConnectionsConfig,\n providerBindings,\n })\n const locator = new ProviderFactoryLocator({\n caches: {},\n singletons: {},\n ...options.context,\n config: locatorConfig,\n })\n for (const selected of input.compiled.resolution.selected) {\n const declaration = selected as unknown as Xl1BrowserProviderDeclaration\n const descriptor = declaration.xl1\n locator.register(descriptor.creatableProvider.factory([\n ...(descriptor.dependencies ?? descriptor.creatableProvider.dependencies),\n ]))\n }\n locator.freeze()\n\n try {\n for (const moniker of input.compiled.declaration.dependencies) {\n await locator.getInstance(moniker)\n }\n } catch (startError) {\n const releaseError = await releaseXl1Providers(locator).catch(error => error)\n if (releaseError !== undefined) {\n throw new AggregateError(\n [startError, releaseError],\n 'XL1 browser provider provisioning and cleanup both failed',\n { cause: startError },\n )\n }\n throw startError\n }\n\n const resolvedConfig = Object.freeze({\n ...options.config,\n actors: input.config.actors,\n connections: input.compiled.config.connections as ConnectionsConfig,\n providerBindings,\n })\n const system = createResolvedProviderSystem({\n config: resolvedConfig,\n locator,\n resolution: createResolvedBrowserProviderPlan(input.compiled.resolution),\n })\n let releasePromise: Promise<void> | undefined\n return {\n release: () => {\n releasePromise ??= releaseXl1Providers(locator)\n return releasePromise\n },\n system,\n }\n }\n}\n\nfunction mergeResolvedProviderBindings(\n authored: ProviderBindingsConfig,\n resolved: Readonly<Record<string, {\n readonly connection?: string\n readonly options?: Readonly<Record<string, unknown>>\n readonly provider?: string\n } | undefined>>,\n): ProviderBindingsConfig {\n return Object.fromEntries(Object.entries(resolved).map(([moniker, binding]) => [\n moniker,\n {\n ...authored[moniker],\n ...binding,\n },\n ]))\n}\n\nasync function releaseXl1Providers(locator: ProviderFactoryLocatorInstance): Promise<void> {\n const instances = await instantiatedProviders(locator)\n for (const instance of instances) instance.requestCancel?.()\n\n const errors: unknown[] = []\n for (const instance of instances.toReversed()) {\n try {\n await stopOrShutdown(instance)\n } catch (error) {\n errors.push(error)\n }\n }\n if (errors.length > 0) {\n throw new AggregateError(errors, `${errors.length} XL1 browser provider(s) failed to stop`)\n }\n}\n\nasync function instantiatedProviders(\n locator: ProviderFactoryLocatorInstance,\n): Promise<(CreatableProviderInstance & { requestCancel?(reason?: unknown): void })[]> {\n const instances = await Promise.all(\n Object.values(locator.context.singletons).map(async value => await value),\n )\n return [...new Set(instances)].filter(isCreatableProviderInstance)\n}\n\nfunction isCreatableProviderInstance(\n value: unknown,\n): value is CreatableProviderInstance & { requestCancel?(reason?: unknown): void } {\n return typeof value === 'object'\n && value !== null\n && 'stop' in value\n && typeof value.stop === 'function'\n}\n"],
|
|
5
|
-
"mappings": ";AAOA,SAAS,2BAA2B;;;ACHpC,SAAS,gCAAgC;
|
|
6
|
-
"names": ["DataLakeViewerMoniker", "XyoGatewayMoniker", "XyoGatewayMoniker", "DataLakeViewerMoniker"
|
|
3
|
+
"sources": ["../../src/launchXl1BrowserSystem.ts", "../../src/Xl1BrowserConfig.ts", "../../src/Xl1BrowserProvider.ts", "../../src/Xl1BrowserSystemActor.ts"],
|
|
4
|
+
"sourcesContent": ["import type {\n BrowserActor,\n BrowserActorCatalog,\n BrowserProviderDescriptor,\n BrowserSystemIdentity,\n BrowserSystemSession,\n} from '@ariestools/browser-kit'\nimport { launchBrowserSystem } from '@ariestools/browser-kit'\nimport type {\n ProviderDescriptor as Xl1ProviderDescriptor,\n ProviderFactoryLocatorInstance,\n} from '@xyo-network/xl1-sdk'\n\nimport {\n parseXl1BrowserSystemConfig,\n toBrowserSystemConfig,\n} from './Xl1BrowserConfig.ts'\nimport {\n createXl1BrowserSystemProvisioner,\n xl1BrowserProviderDeclarations,\n type Xl1BrowserProviderRuntimeContext,\n} from './Xl1BrowserProvider.ts'\nimport { createXl1BrowserActorCatalog } from './Xl1BrowserSystemActor.ts'\n\n/** Inputs for launching one owner-resolved XL1 browser provider system. */\nexport interface LaunchXl1BrowserSystemOptions<TActor extends BrowserActor = BrowserActor> {\n readonly actorCatalog?: BrowserActorCatalog<TActor, ProviderFactoryLocatorInstance>\n readonly config: unknown\n readonly context?: Xl1BrowserProviderRuntimeContext\n readonly host?: string\n readonly identity?: BrowserSystemIdentity\n readonly providerCandidates?: readonly Xl1ProviderDescriptor[]\n readonly readyTimeoutMs?: number\n}\n\n/** Parses, resolves, provisions, and starts one XL1 system from browser-safe config. */\nexport async function launchXl1BrowserSystem<TActor extends BrowserActor = BrowserActor>(\n options: LaunchXl1BrowserSystemOptions<TActor>,\n): Promise<BrowserSystemSession<TActor, ProviderFactoryLocatorInstance>> {\n const config = parseXl1BrowserSystemConfig(options.config)\n const actorCatalog = options.actorCatalog\n ?? createXl1BrowserActorCatalog() as BrowserActorCatalog<TActor, ProviderFactoryLocatorInstance>\n const providerDescriptors = xl1BrowserProviderDeclarations(options.providerCandidates)\n return await launchBrowserSystem({\n actorCatalog,\n config: toBrowserSystemConfig(config),\n host: options.host,\n identity: options.identity,\n providerDescriptors: providerDescriptors as unknown as BrowserProviderDescriptor[],\n provision: createXl1BrowserSystemProvisioner({\n config,\n context: options.context,\n }),\n readyTimeoutMs: options.readyTimeoutMs,\n })\n}\n", "import type {\n BrowserActorSelection,\n BrowserSystemConfig,\n} from '@ariestools/browser-kit'\nimport { parseBrowserSystemConfig } from '@ariestools/browser-kit'\nimport type {\n ConnectionsConfig,\n LocatorConfig,\n PrimeCachesMode,\n ProviderBindingsConfig,\n RestGatewayConfig,\n} from '@xyo-network/xl1-sdk'\nimport {\n BlockViewerMoniker,\n ChainContractViewerMoniker,\n ChainStateViewerMoniker,\n DataLakeViewerMoniker,\n FinalizationViewerMoniker,\n IndexViewerMoniker,\n NetworkStakeStepRewardsByPositionViewerMoniker,\n parseLocatorConfigFields,\n restConnectionFromS3Bucket,\n restGatewayConfigFromEndpoint,\n XyoConnectionMoniker,\n XyoGatewayMoniker,\n} from '@xyo-network/xl1-sdk'\n\nimport {\n SimpleXyoConnectionViewerProviderId,\n SimpleXyoGatewayProviderId,\n} from './Xl1BrowserProvider.ts'\nimport {\n Xl1BrowserSystemActorType,\n Xl1BrowserSystemWithDataLakeActorType,\n} from './Xl1BrowserSystemActor.ts'\n\n/** Authored XL1 locator fields plus browser actor selections. */\nexport interface Xl1BrowserSystemConfig extends LocatorConfig {\n readonly actors: readonly BrowserActorSelection[]\n}\n\n/** Options for the standard read-only REST-backed XL1 browser system. */\nexport interface CreateXl1RestBrowserSystemConfigOptions {\n readonly actors?: readonly BrowserActorSelection[]\n readonly dataLakeEndpoint?: string\n readonly endpoint: string\n readonly host?: string\n readonly layout?: Xl1RestEndpointLayout\n readonly primeCaches?: PrimeCachesMode\n}\n\n/** How the REST gateway's finalized, chain-state, and index URLs are derived from its endpoint. */\nexport type Xl1RestEndpointLayout = 'path' | 'subdomain'\n\n/** Parses XL1 locator fields and browser actor selections without importing code from config. */\nexport function parseXl1BrowserSystemConfig(input: unknown): Xl1BrowserSystemConfig {\n const locatorConfig = parseLocatorConfigFields(input)\n const browserConfig = parseBrowserSystemConfig({\n actors: isRecord(input) ? input['actors'] : undefined,\n connections: locatorConfig.connections,\n providerBindings: toBrowserProviderBindings(locatorConfig.providerBindings),\n })\n return Object.freeze({\n ...locatorConfig,\n actors: Object.freeze([...(browserConfig.actors ?? [])]),\n })\n}\n\n/** Projects the XL1 config onto the neutral fields browser-kit compiles. */\nexport function toBrowserSystemConfig(\n config: Xl1BrowserSystemConfig,\n): BrowserSystemConfig {\n return {\n actors: config.actors,\n connections: config.connections,\n providerBindings: toBrowserProviderBindings(config.providerBindings),\n }\n}\n\n/** Creates explicit REST connections and provider bindings for a read-only XL1 gateway actor. */\nexport function createXl1RestBrowserSystemConfig(\n options: CreateXl1RestBrowserSystemConfigOptions,\n): Xl1BrowserSystemConfig {\n const buckets = options.layout === 'path'\n ? restGatewayConfigFromPathEndpoint(options.endpoint)\n : restGatewayConfigFromEndpoint(options.endpoint)\n const finalized = buckets.finalized\n if (finalized === undefined) throw new Error('XL1 REST gateway has no finalized bucket')\n\n const connections: ConnectionsConfig = {\n 'rest-chain-state': restConnectionFromS3Bucket(buckets.chainState ?? finalized),\n 'rest-finalized': restConnectionFromS3Bucket(finalized),\n 'rest-index': restConnectionFromS3Bucket(buckets.index ?? finalized),\n }\n const providerBindings: ProviderBindingsConfig = {\n [BlockViewerMoniker]: { connection: 'rest-finalized' },\n [ChainContractViewerMoniker]: { connection: 'rest-chain-state' },\n [ChainStateViewerMoniker]: { connection: 'rest-chain-state' },\n [FinalizationViewerMoniker]: { connection: 'rest-finalized' },\n [IndexViewerMoniker]: { connection: 'rest-index' },\n [XyoConnectionMoniker]: { provider: SimpleXyoConnectionViewerProviderId },\n [XyoGatewayMoniker]: { provider: SimpleXyoGatewayProviderId },\n }\n if (options.dataLakeEndpoint !== undefined) {\n connections['rest-data-lake'] = {\n baseUrl: options.dataLakeEndpoint,\n type: 'rest',\n }\n providerBindings[DataLakeViewerMoniker] = { connection: 'rest-data-lake' }\n }\n if (options.primeCaches !== undefined) {\n providerBindings[NetworkStakeStepRewardsByPositionViewerMoniker] = { primeCaches: options.primeCaches }\n }\n\n return parseXl1BrowserSystemConfig({\n actors: options.actors ?? [{\n host: options.host,\n type: options.dataLakeEndpoint === undefined\n ? Xl1BrowserSystemActorType\n : Xl1BrowserSystemWithDataLakeActorType,\n }],\n connections,\n providerBindings,\n })\n}\n\nfunction restGatewayConfigFromPathEndpoint(\n endpoint: string,\n): Required<Pick<RestGatewayConfig, 'chainState' | 'finalized' | 'index'>> {\n const baseUrl = endpoint.endsWith('/') ? endpoint.slice(0, -1) : endpoint\n return {\n chainState: { readUrl: `${baseUrl}/state` },\n finalized: { readUrl: `${baseUrl}/blocks` },\n index: { readUrl: `${baseUrl}/indexes` },\n }\n}\n\nfunction toBrowserProviderBindings(\n bindings: ProviderBindingsConfig,\n): NonNullable<BrowserSystemConfig['providerBindings']> {\n return Object.fromEntries(Object.entries(bindings).map(([moniker, binding]) => [\n moniker,\n binding === undefined\n ? {}\n : {\n connection: binding.connection,\n options: binding.options,\n provider: binding.provider,\n },\n ]))\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n", "import { stopOrShutdown } from '@ariestools/actor'\nimport type { BrowserSystemProvisioner } from '@ariestools/browser-kit'\nimport { createResolvedBrowserProviderPlan } from '@ariestools/browser-kit'\nimport { createResolvedProviderSystem } from '@ariestools/provider-model'\nimport type {\n ConnectionsConfig,\n CreatableProviderContext,\n CreatableProviderInstance,\n ProviderBindingsConfig,\n ProviderDescriptor as Xl1ProviderDescriptor,\n ProviderFactoryLocatorInstance,\n} from '@xyo-network/xl1-sdk'\nimport {\n allProviderCandidates,\n compileLocatorConfig,\n providerCandidateFromClass,\n ProviderFactoryLocator,\n SimpleXyoConnectionViewer,\n SimpleXyoGateway,\n} from '@xyo-network/xl1-sdk'\n\nimport type { Xl1BrowserSystemConfig } from './Xl1BrowserConfig.ts'\n\n/** Stable browser-provider identifier retained across production minification. */\nexport const SimpleXyoConnectionViewerProviderId = 'SimpleXyoConnectionViewer'\n/** Stable browser-provider identifier retained across production minification. */\nexport const SimpleXyoGatewayProviderId = 'SimpleXyoGateway'\n\n/** Browser-kit plan metadata retaining the XL1 provider class used by the provisioner. */\nexport interface Xl1BrowserProviderDeclaration {\n readonly connectionTypes: readonly string[]\n readonly dependencies: readonly string[]\n readonly id: string\n readonly monikers: readonly string[]\n readonly xl1: Xl1ProviderDescriptor\n}\n\n/** Non-serializable XL1 runtime homes supplied by the realm that owns the system. */\nexport type Xl1BrowserProviderRuntimeContext = Omit<\n CreatableProviderContext,\n 'config' | 'locator'\n>\n\n/** Options captured by the XL1 browser-system provisioner. */\nexport interface CreateXl1BrowserSystemProvisionerOptions {\n readonly config: Xl1BrowserSystemConfig\n readonly context?: Xl1BrowserProviderRuntimeContext\n}\n\n/** Adapts one XL1 provider candidate into neutral browser-kit plan metadata. */\nexport function xl1BrowserProviderDeclaration(\n descriptor: Xl1ProviderDescriptor,\n): Xl1BrowserProviderDeclaration {\n return Object.freeze({\n connectionTypes: Object.freeze([...descriptor.connectionTypes]),\n dependencies: Object.freeze([...(descriptor.dependencies ?? [])]),\n id: descriptor.id,\n monikers: Object.freeze([...descriptor.satisfies]),\n xl1: descriptor,\n })\n}\n\n/** Returns the XL1 provider catalog available to browser-system configuration. */\nexport function xl1BrowserProviderCandidates(): Xl1ProviderDescriptor[] {\n return [\n ...allProviderCandidates(),\n providerCandidateFromClass(SimpleXyoConnectionViewer, SimpleXyoConnectionViewerProviderId),\n providerCandidateFromClass(SimpleXyoGateway, SimpleXyoGatewayProviderId),\n ]\n}\n\n/** Adapts an XL1 provider catalog for browser-kit planning. */\nexport function xl1BrowserProviderDeclarations(\n candidates: readonly Xl1ProviderDescriptor[] = xl1BrowserProviderCandidates(),\n): Xl1BrowserProviderDeclaration[] {\n return candidates.map(xl1BrowserProviderDeclaration)\n}\n\n/** Creates the owner-realm provisioner that instantiates one resolved XL1 locator. */\nexport function createXl1BrowserSystemProvisioner(\n options: CreateXl1BrowserSystemProvisionerOptions,\n): BrowserSystemProvisioner<ProviderFactoryLocatorInstance> {\n return async (input) => {\n const providerBindings = mergeResolvedProviderBindings(\n options.config.providerBindings,\n input.compiled.config.providerBindings,\n )\n const locatorConfig = compileLocatorConfig({\n ...options.config,\n connections: input.compiled.config.connections as ConnectionsConfig,\n providerBindings,\n })\n const locator = new ProviderFactoryLocator({\n caches: {},\n singletons: {},\n ...options.context,\n config: locatorConfig,\n })\n for (const selected of input.compiled.resolution.selected) {\n const declaration = selected as unknown as Xl1BrowserProviderDeclaration\n const descriptor = declaration.xl1\n locator.register(descriptor.creatableProvider.factory([\n ...(descriptor.dependencies ?? descriptor.creatableProvider.dependencies),\n ]))\n }\n locator.freeze()\n\n try {\n for (const moniker of input.compiled.declaration.dependencies) {\n await locator.getInstance(moniker)\n }\n } catch (startError) {\n const releaseError = await releaseXl1Providers(locator).catch(error => error)\n if (releaseError !== undefined) {\n throw new AggregateError(\n [startError, releaseError],\n 'XL1 browser provider provisioning and cleanup both failed',\n { cause: startError },\n )\n }\n throw startError\n }\n\n const resolvedConfig = Object.freeze({\n ...options.config,\n actors: input.config.actors,\n connections: input.compiled.config.connections as ConnectionsConfig,\n providerBindings,\n })\n const system = createResolvedProviderSystem({\n config: resolvedConfig,\n locator,\n resolution: createResolvedBrowserProviderPlan(input.compiled.resolution),\n })\n let releasePromise: Promise<void> | undefined\n return {\n release: () => {\n releasePromise ??= releaseXl1Providers(locator)\n return releasePromise\n },\n system,\n }\n }\n}\n\nfunction mergeResolvedProviderBindings(\n authored: ProviderBindingsConfig,\n resolved: Readonly<Record<string, {\n readonly connection?: string\n readonly options?: Readonly<Record<string, unknown>>\n readonly provider?: string\n } | undefined>>,\n): ProviderBindingsConfig {\n return Object.fromEntries(Object.entries(resolved).map(([moniker, binding]) => [\n moniker,\n {\n ...authored[moniker],\n ...binding,\n },\n ]))\n}\n\nasync function releaseXl1Providers(locator: ProviderFactoryLocatorInstance): Promise<void> {\n const instances = await instantiatedProviders(locator)\n for (const instance of instances) instance.requestCancel?.()\n\n const errors: unknown[] = []\n for (const instance of instances.toReversed()) {\n try {\n await stopOrShutdown(instance)\n } catch (error) {\n errors.push(error)\n }\n }\n if (errors.length > 0) {\n throw new AggregateError(errors, `${errors.length} XL1 browser provider(s) failed to stop`)\n }\n}\n\nasync function instantiatedProviders(\n locator: ProviderFactoryLocatorInstance,\n): Promise<(CreatableProviderInstance & { requestCancel?(reason?: unknown): void })[]> {\n const instances = await Promise.all(\n Object.values(locator.context.singletons).map(async value => await value),\n )\n return [...new Set(instances)].filter(isCreatableProviderInstance)\n}\n\nfunction isCreatableProviderInstance(\n value: unknown,\n): value is CreatableProviderInstance & { requestCancel?(reason?: unknown): void } {\n return typeof value === 'object'\n && value !== null\n && 'stop' in value\n && typeof value.stop === 'function'\n}\n", "import type {\n ProviderActorContext,\n ProviderActorParams,\n} from '@ariestools/actor'\nimport { ProviderActor } from '@ariestools/actor'\nimport type {\n BrowserActor,\n ResolvedBrowserProviderPlan,\n ResolvedBrowserSystemConfig,\n} from '@ariestools/browser-kit'\nimport { BrowserActorCatalog as BrowserActorCatalogInstance } from '@ariestools/browser-kit'\nimport type { CreatableName } from '@ariestools/sdk'\nimport type {\n ProviderFactoryLocatorInstance,\n XyoGateway,\n} from '@xyo-network/xl1-sdk'\nimport {\n DataLakeViewerMoniker,\n XyoGatewayMoniker,\n} from '@xyo-network/xl1-sdk'\n\nexport const Xl1BrowserSystemActorType = 'xl1-system' as const\nexport const Xl1BrowserSystemWithDataLakeActorType = 'xl1-system-with-data-lake' as const\n\nexport interface Xl1BrowserSystemActorParams extends ProviderActorParams<\n ProviderFactoryLocatorInstance,\n ResolvedBrowserSystemConfig,\n unknown,\n ResolvedBrowserProviderPlan\n> {}\n\n/** Resident actor representing one configured XL1 gateway system. */\nexport class Xl1BrowserSystemActor extends ProviderActor<Xl1BrowserSystemActorParams> {\n /** Resolves the gateway owned by this actor's immutable provider system. */\n async getGateway(): Promise<XyoGateway> {\n if (this.status !== 'started') {\n throw new Error(`XL1 browser system actor is not running (status: ${this.status})`)\n }\n return await this.getProvider<XyoGateway>(XyoGatewayMoniker)\n }\n}\n\nexport const Xl1BrowserSystemActorDependencies = [XyoGatewayMoniker] as const\nexport const Xl1BrowserSystemWithDataLakeActorDependencies = [\n XyoGatewayMoniker,\n DataLakeViewerMoniker,\n] as const\n\n/** Creates the default actor catalog and optionally installs application actors. */\nexport function createXl1BrowserActorCatalog() {\n const catalog = new BrowserActorCatalogInstance<BrowserActor, ProviderFactoryLocatorInstance>()\n const create = async (\n id: string,\n providerContext: ProviderActorContext<\n ProviderFactoryLocatorInstance,\n ResolvedBrowserSystemConfig,\n unknown,\n ResolvedBrowserProviderPlan\n >,\n ) => await Xl1BrowserSystemActor.create({\n name: id as CreatableName,\n providerContext,\n })\n catalog.register({\n create: async ({ id, providerContext }) => await create(\n id,\n providerContext as ProviderActorContext<\n ProviderFactoryLocatorInstance,\n ResolvedBrowserSystemConfig,\n unknown,\n ResolvedBrowserProviderPlan\n >,\n ),\n dependencies: Xl1BrowserSystemActorDependencies,\n type: Xl1BrowserSystemActorType,\n })\n catalog.register({\n create: async ({ id, providerContext }) => await create(\n id,\n providerContext as ProviderActorContext<\n ProviderFactoryLocatorInstance,\n ResolvedBrowserSystemConfig,\n unknown,\n ResolvedBrowserProviderPlan\n >,\n ),\n dependencies: Xl1BrowserSystemWithDataLakeActorDependencies,\n type: Xl1BrowserSystemWithDataLakeActorType,\n })\n return catalog\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["DataLakeViewerMoniker", "XyoGatewayMoniker", "XyoGatewayMoniker", "DataLakeViewerMoniker"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@xyo-network/xl1-browser-system",
|
|
4
|
-
"version": "5.0.
|
|
4
|
+
"version": "5.0.13",
|
|
5
5
|
"description": "Config-driven XL1 provider actor systems for browser runtimes",
|
|
6
6
|
"homepage": "https://xylabs.com",
|
|
7
7
|
"bugs": {
|
|
@@ -41,14 +41,18 @@
|
|
|
41
41
|
],
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@ariestools/provider-model": "~1.1.1",
|
|
44
|
-
"@xyo-network/xl1-sdk": "~5.0.
|
|
44
|
+
"@xyo-network/xl1-sdk": "~5.0.13"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@ariestools/actor": "~1.1.1",
|
|
48
48
|
"@ariestools/actor-model": "~1.1.1",
|
|
49
49
|
"@ariestools/browser-kit": "~0.1.1",
|
|
50
|
+
"@ariestools/browser-kit-page": "~0.1.1",
|
|
51
|
+
"@ariestools/browser-kit-plugin": "~0.1.1",
|
|
52
|
+
"@ariestools/browser-kit-service-worker": "~0.1.1",
|
|
53
|
+
"@ariestools/browser-kit-worker": "~0.1.1",
|
|
50
54
|
"@ariestools/provider": "~1.1.1",
|
|
51
|
-
"@ariestools/sdk": "~8.1.
|
|
55
|
+
"@ariestools/sdk": "~8.1.7",
|
|
52
56
|
"@ariestools/toolchain": "~8.7.26",
|
|
53
57
|
"@ariestools/tsconfig": "~8.7.26",
|
|
54
58
|
"@ariestools/tsconfig-dom": "~8.7.26",
|
|
@@ -60,6 +64,7 @@
|
|
|
60
64
|
"eslint": "~10.8.0",
|
|
61
65
|
"ethers": "~6.17.0",
|
|
62
66
|
"msw": "~2.15.0",
|
|
67
|
+
"playwright": "~1.62.1",
|
|
63
68
|
"typescript": "~6.0.3",
|
|
64
69
|
"vite": "~8.2.0",
|
|
65
70
|
"vitest": "~4.1.10",
|
|
@@ -77,7 +82,10 @@
|
|
|
77
82
|
"access": "public"
|
|
78
83
|
},
|
|
79
84
|
"scripts": {
|
|
85
|
+
"example:build": "vite build --config examples/vite.config.ts && vite build --config examples/extension/vite.config.ts",
|
|
86
|
+
"example:serve": "vite preview --config examples/vite.config.ts --host 127.0.0.1 --port 4173",
|
|
80
87
|
"test": "vitest run",
|
|
81
|
-
"test:ci": "vitest run"
|
|
88
|
+
"test:ci": "vitest run",
|
|
89
|
+
"test:e2e": "playwright test --config test/e2e/playwright.config.ts"
|
|
82
90
|
}
|
|
83
91
|
}
|