bare-stow 0.1.9 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,125 +1,291 @@
1
1
  import URL from 'bare-url'
2
2
  import { PackOptions } from 'bare-pack'
3
3
 
4
- /** A single generated source artifact, such as a harness or a type declaration. */
5
- interface Artifact {
4
+ /** The source of a generated module, together with its type declaration. */
5
+ interface Generated {
6
+ /** The module's source text. */
7
+ source: string
6
8
  /**
7
- * The file extension the artifact should be written with alongside the primary output, or unset
8
- * to write it to the primary output path itself.
9
+ * The module's type declaration, written next to it under the name chosen by the language, or
10
+ * unset when the module has none.
9
11
  */
10
- extension?: string
11
- /** The artifact's source text. */
12
- source: string
12
+ types?: string | null
13
+ /**
14
+ * The packages the module imports, mapped to what the language's manifest needs to declare them,
15
+ * such as a version range for `javascript` and `python`, a version for `kotlin`, or `{ url, from, products }` for `swift`.
16
+ */
17
+ dependencies?: Record<string, unknown>
18
+ }
19
+
20
+ /** Where a language writes the harness package. */
21
+ interface Layout {
22
+ /** The harness module. */
23
+ harness: URL
24
+ /** The name of the package, written into the manifest. */
25
+ name: string
26
+ /** The package manifest declaring the dependencies of the generated modules. */
27
+ manifest: URL
28
+ /** The directory the bundle is written to, or unset to write it next to the harness. */
29
+ artifacts?: URL
30
+ /** The directory the addons of a linked target are linked into, or unset if unsupported. */
31
+ addons?: URL
32
+ /** The directory the assets of linked bundles are linked into, or unset if unsupported. */
33
+ resources?: URL
34
+ /**
35
+ * Whether the files written next to the bundle are listed in `<bundle>.files`, one `/<path>` per
36
+ * line, for a harness that extracts them along with the bundle.
37
+ */
38
+ listing?: boolean
13
39
  }
14
40
 
15
- type TargetName = 'bare-sidecar' | 'bare-worker'
41
+ /** The context passed to a language's `manifest()`. */
42
+ interface ManifestContext {
43
+ /** The package name, as given by the layout. */
44
+ name: string
45
+ /** The packages the generated modules import, as declared by their generators. */
46
+ dependencies: Record<string, unknown>
47
+ /** The options resolved by the language. */
48
+ options: LanguageOptions
49
+ /** The host triples the bundle is packed for. */
50
+ hosts: string[]
51
+ /** References from the manifest to the bundle and the files written next to it. */
52
+ artifacts: string[]
53
+ /** References from the manifest to the resources linked for the addons of a linked target. */
54
+ addons: string[]
55
+ }
16
56
 
17
57
  /**
18
- * The context passed to a target's `generate()`, describing the bundle to embed and the RPC wiring
19
- * to splice in.
58
+ * Options resolved by a language from those given and passed to every provider generating code in
59
+ * that language. A target may pin some of them through `TargetLanguage.options`.
20
60
  */
21
- interface TargetContext {
22
- /** The module specifier the harness uses to load the bundle, relative to the harness itself. */
23
- bundleSpecifier: string
24
- /** The identifier bound to the IPC stream in generated harness code. */
25
- ipc: string
26
- /** The identifier bound to the RPC client/server in generated harness code. */
27
- rpc: string
28
- /** The module system the harness is generated in, `'esm'` or `'cjs'`. */
61
+ type LanguageOptions = Record<string, unknown>
62
+
63
+ /** The options of the built-in `javascript` language. */
64
+ interface JavaScriptOptions {
65
+ /**
66
+ * The module system of the generated code, written as the `type` of the harness package. Either
67
+ * `'esm'`, the default, or `'cjs'`.
68
+ */
29
69
  module: 'esm' | 'cjs'
70
+ }
71
+
72
+ /** The options of the built-in `kotlin` language. */
73
+ interface KotlinOptions {
74
+ /** The package of the generated code, such as `'com.example.core'`, which is also its namespace. */
75
+ package: string
76
+ /** The platform of the module, either `'android'`, the default, or `'jvm'`. */
77
+ platform: 'android' | 'jvm'
78
+ }
79
+
80
+ type LanguageName = 'javascript' | 'kotlin' | 'python' | 'swift'
81
+
82
+ /**
83
+ * A host language, such as `javascript`, describing how generated modules in that language are laid
84
+ * out, named, referenced, and declared.
85
+ */
86
+ interface Language {
87
+ /** The language's name, used to select its entry in a target's or RPC library's `languages`. */
88
+ name: string
89
+ /**
90
+ * Resolve the options for generating code from those given.
91
+ * @param given - The options given through `StowOptions.languageOptions`.
92
+ * @throws An option is unknown or has an invalid value.
93
+ */
94
+ options(given?: LanguageOptions): LanguageOptions
95
+ /**
96
+ * Lay the generated files out in the package directory `out`.
97
+ * @param out - The package directory, as a URL ending in a slash.
98
+ * @param options - The options resolved by the language, with any pinned by the target applied.
99
+ * @throws `out` is not valid as a package for the language.
100
+ */
101
+ layout(out: URL, options: LanguageOptions): Layout
102
+ /**
103
+ * Name a module generated alongside `url`.
104
+ * @param url - The module the sibling is generated alongside.
105
+ * @param name - The name of the sibling, such as `'client'`.
106
+ */
107
+ sibling(url: URL, name: string): URL
108
+ /**
109
+ * Name the type declaration of the module at `url`. Required when the language's generators
110
+ * return separate type declarations.
111
+ * @param url - The module to name the type declaration of.
112
+ */
113
+ types?(url: URL): URL
114
+ /**
115
+ * Render a reference from the module at `from` to the file at `to`, such as a relative specifier.
116
+ * @param from - The referencing module.
117
+ * @param to - The referenced file.
118
+ */
119
+ reference(from: URL, to: URL): string
120
+ /**
121
+ * Render the manifest named by the layout.
122
+ * @param context - The manifest context describing the package to declare.
123
+ */
124
+ manifest(context: ManifestContext): string
125
+ }
126
+
127
+ type TargetName = 'bare-kit' | 'bare-sidecar' | 'bare-worker'
128
+
129
+ /** The context passed to a target language's `generate()`. */
130
+ interface TargetContext<O extends LanguageOptions = LanguageOptions> {
131
+ /** A reference from the harness to the bundle. */
132
+ bundle: string
133
+ /**
134
+ * A reference from the harness to the generated RPC client module, or `null` when no client was
135
+ * requested. The module exposes `attach(ipc, handlers)`, which binds the client to the IPC handle
136
+ * once `handlers` has registered the handlers of the client, and the `Handlers` type.
137
+ */
138
+ client: string | null
139
+ /**
140
+ * The application resource holding the assets of the bundle, which is then started as
141
+ * `<resources>.bundle`, or `null` if the assets are next to the bundle.
142
+ */
143
+ resources: string | null
144
+ /** The options resolved by the language, with any pinned by the target applied. */
145
+ options: O
146
+ }
147
+
148
+ /** The context passed to a target language's `link()`. */
149
+ interface TargetLinkContext<O extends LanguageOptions = LanguageOptions> {
150
+ /** The options resolved by the language, with any pinned by the target applied. */
151
+ options: O
152
+ }
153
+
154
+ /** The module and dependencies of a package of linked addons. */
155
+ interface Linked {
156
+ /** The module's source text, written in place of the harness, or unset for none. */
157
+ source?: string | null
158
+ /** The packages that load the addons, declared as for `Generated.dependencies`. */
159
+ dependencies?: Record<string, unknown>
160
+ }
161
+
162
+ /** A target's support for one host language. */
163
+ interface TargetLanguage<O extends LanguageOptions = LanguageOptions> {
164
+ /** Options pinned over those the language would otherwise resolve. */
165
+ options?: Partial<O>
30
166
  /**
31
- * The resolved client RPC wiring to splice into the harness, or `null` when no client RPC was
32
- * requested.
167
+ * Generate the harness for `context`.
168
+ * @param context - The target context describing the bundle and RPC client to reference.
33
169
  */
34
- client: RPCClient | null
170
+ generate(context: TargetContext<O>): Generated
171
+ /**
172
+ * Generate the module of a package of addons for `stow.link()`, which requires it.
173
+ * @param context - The context describing the options to generate for.
174
+ */
175
+ link?(context: TargetLinkContext<O>): Linked
176
+ }
177
+
178
+ /** Options resolved by a target from those given. */
179
+ type TargetOptions = Record<string, unknown>
180
+
181
+ /** The context passed to the properties of a target that are functions. */
182
+ interface TargetResolveContext<O extends LanguageOptions = LanguageOptions> {
183
+ /** The name of the language of the harness. */
184
+ language: string
185
+ /** The options resolved by the language, with any pinned by the target applied. */
186
+ options: O
187
+ /** The options resolved by the target. */
188
+ targetOptions: TargetOptions
35
189
  }
36
190
 
37
191
  /**
38
- * A bundling target, such as `bare-sidecar` or `bare-worker`, describing how to package and boot a
39
- * bundle on a given host runtime.
192
+ * A property of a target, or a function resolving it from the language of the harness and the
193
+ * options it resolved, such as hosts that differ between languages.
194
+ */
195
+ type Resolvable<T> = T | ((context: TargetResolveContext) => T)
196
+
197
+ /**
198
+ * A bundling target, such as `bare-sidecar` or `bare-worker`, describing how to package a bundle and
199
+ * boot it from a host in each of the languages it supports.
40
200
  */
41
201
  interface Target {
42
202
  /** The target's name. */
43
203
  name: string
44
- /** Whether the bundle links against its dependencies rather than inlining them. */
45
- linked: boolean
204
+ /**
205
+ * Whether the bundle owns its `'process'` or shares one by running in a `'thread'`. Only a bundle
206
+ * that owns its process handles signals.
207
+ */
208
+ isolation: Resolvable<'process' | 'thread'>
209
+ /**
210
+ * Whether the bundle links against its dependencies rather than inlining them. A linked bundle
211
+ * also leaves its assets out, as files that the runtime loads.
212
+ */
213
+ linked: Resolvable<boolean>
214
+ /**
215
+ * Whether addons and assets are linked into the harness `'package'`, the default, or left to the
216
+ * `'app'`, which links them with `stow.link()`.
217
+ */
218
+ linking?: Resolvable<'package' | 'app'>
46
219
  /**
47
220
  * Whether native addons and/or assets are written out as sibling files instead of being inlined
48
221
  * into the bundle.
49
222
  */
50
- offload: boolean | { addons?: boolean; assets?: boolean }
223
+ offload: Resolvable<boolean | { addons?: boolean; assets?: boolean }>
51
224
  /** The encoding format of the written bundle artifact. */
52
- format: 'bundle' | 'bundle.cjs' | 'bundle.mjs' | 'bundle.json'
225
+ format: Resolvable<'bundle' | 'bundle.cjs' | 'bundle.mjs' | 'bundle.json'>
53
226
  /**
54
227
  * The text encoding used when the bundle format wraps the bundle as a string, or `null` when the
55
228
  * bundle is written as raw bytes.
56
229
  */
57
- encoding: string | null
58
- /** The file extension used for the target's harness artifact. */
59
- extension: string
60
- /**
61
- * The module system the harness is generated in, `'esm'` or `'cjs'`. When unset, it follows the
62
- * output path's extension or nearest `package.json` `type`.
63
- */
64
- module?: 'esm' | 'cjs'
230
+ encoding: Resolvable<string | null>
231
+ /** The file extension of the bundle, such as `'.bundle'`. */
232
+ extension: Resolvable<string>
65
233
  /** The host triples the target supports. */
66
- hosts: string[]
234
+ hosts: Resolvable<string[]>
235
+ /** The host languages the target supports, keyed by language name. */
236
+ languages: Record<string, TargetLanguage>
67
237
  /**
68
- * Generate the harness artifacts for `context`.
69
- * @param context - The target context describing the bundle to embed and the RPC wiring to splice
70
- * in.
238
+ * Resolve the options of the target from those given. Without it, the target accepts no options.
239
+ * @param given - The options given through `StowOptions.targetOptions`.
240
+ * @throws An option is unknown or has an invalid value.
71
241
  */
72
- generate(context: TargetContext): Artifact[]
242
+ options?(given: TargetOptions): TargetOptions
73
243
  }
74
244
 
75
245
  type RPCName = 'bare-rpc'
76
246
 
77
- /** The context passed to an RPC adapter's `generate()`. */
78
- interface RPCContext {
79
- /** The identifier bound to the IPC stream in generated code. */
80
- ipc: string
81
- /** The identifier bound to the RPC client/server in generated code. */
82
- rpc: string
83
- /** The module system the generated code targets, `'esm'` or `'cjs'`. */
84
- module: 'esm' | 'cjs'
247
+ /** The context passed to an RPC language's `generate()`. */
248
+ interface RPCContext<O extends LanguageOptions = LanguageOptions> {
85
249
  /**
86
- * Whether the generated wiring is for the `'client'` (harness side) or `'server'` (bundle entry
87
- * shim side).
250
+ * Whether the module binds the `'client'` in the harness or the `'server'` in the bundle. The
251
+ * server is always generated as JavaScript with `{ module: 'esm' }`.
88
252
  */
89
253
  role: 'client' | 'server'
254
+ /** The options resolved by the language. */
255
+ options: O
90
256
  }
91
257
 
92
- /**
93
- * An RPC library adapter that generates the wiring code spliced into a stowed bundle's harness or
94
- * entry shim.
95
- */
96
- interface RPC {
97
- /** The RPC adapter's name. */
98
- name: string
258
+ /** An RPC library's support for one language. */
259
+ interface RPCLanguage<O extends LanguageOptions = LanguageOptions> {
99
260
  /**
100
- * Generate the RPC wiring artifacts for `context`.
101
- * @param context - The RPC context describing the identifiers, module system, and role to
102
- * generate wiring for.
261
+ * Generate a module exposing `attach(ipc, handlers)`, which calls `handlers` to register the
262
+ * handlers of an RPC instance, binds it to the IPC handle, and returns it, and the `Handlers`
263
+ * type. The handlers are registered first so that none of the requests and events of the bundle
264
+ * arrive before them.
265
+ * @param context - The RPC context describing the role and language options to generate for.
103
266
  */
104
- generate(context: RPCContext): Artifact[]
267
+ generate(context: RPCContext<O>): Generated
105
268
  }
106
269
 
107
- /**
108
- * The resolved client RPC wiring, carrying both the runtime source to splice into the harness and
109
- * the type declaration to splice into the harness's `.d.ts`.
110
- */
111
- interface RPCClient {
112
- /** The generated runtime source for the client RPC wiring. */
113
- source: string
114
- /** The generated type declaration for the client RPC wiring. */
115
- type: string
270
+ /** An RPC library, describing how to bind it to the IPC handle in each language it supports. */
271
+ interface RPC {
272
+ /** The RPC library's name. */
273
+ name: string
274
+ /** The languages the RPC library supports, keyed by language name. */
275
+ languages: Record<string, RPCLanguage>
116
276
  }
117
277
 
118
278
  /** Options for `stow()`. */
119
- interface StowOptions extends Omit<PackOptions, 'offload' | 'linked' | 'resolve' | 'aliases'> {
120
- /** The RPC library (or its name) to wire into the harness. */
279
+ interface StowOptions extends Omit<PackOptions, 'offload' | 'linked' | 'resolve'> {
280
+ /** The language of the harness (or its name). Defaults to `javascript`. */
281
+ language?: Language | LanguageName
282
+ /** The options given to the language, such as `{ module: 'cjs' }` for `javascript`. */
283
+ languageOptions?: LanguageOptions
284
+ /** The options given to the target. */
285
+ targetOptions?: TargetOptions
286
+ /** The RPC library (or its name) to bind in the harness. */
121
287
  client?: RPC | RPCName
122
- /** The RPC library (or its name) to wire into the bundle's entry shim. */
288
+ /** The RPC library (or its name) to bind in the bundle's entry shim. */
123
289
  server?: RPC | RPCName
124
290
  /**
125
291
  * Resolve a target name to a `Target`, overriding the default target resolution.
@@ -131,27 +297,56 @@ interface StowOptions extends Omit<PackOptions, 'offload' | 'linked' | 'resolve'
131
297
  * @param name - The RPC name to resolve to an `RPC`.
132
298
  */
133
299
  resolveRPC?(name: string): RPC
300
+ /**
301
+ * Resolve a language name to a `Language`, overriding the default language resolution.
302
+ * @param name - The language name to resolve to a `Language`.
303
+ */
304
+ resolveLanguage?(name: string): Language
305
+ /**
306
+ * Read the source of the module at `url`, or `null` if there is none, such as to stow modules
307
+ * that aren't written to disk. Defaults to reading the file.
308
+ */
309
+ readModule?: (url: URL) => Promise<Uint8Array | string | null>
310
+ /** List the files under the prefix `url`. Defaults to listing the directory. */
311
+ listPrefix?: (url: URL) => AsyncIterable<URL>
312
+ /** Resolve the module at `url`. Defaults to its real path, following symbolic links. */
313
+ resolveModule?: (url: URL) => Promise<URL>
314
+ }
315
+
316
+ /** Options for `stow.link()`, which shape the graphs as for `stow()`. */
317
+ interface LinkOptions extends Omit<StowOptions, 'client' | 'base' | 'resolveRPC'> {
318
+ /** Resolve an RPC name to an `RPC`, for the server bound in the entry shims. */
319
+ resolveRPC?(name: string): RPC
134
320
  }
135
321
 
136
322
  /** An artifact written by `stow()`, yielded once its file has been written. */
137
323
  interface StowArtifact {
138
324
  /** The file URL the artifact was written to. */
139
325
  url: URL
326
+ /**
327
+ * For the bundle, the directory that its modules are named relative to: the `base` option, or
328
+ * the closest directory containing every bundled module.
329
+ */
330
+ base?: URL
140
331
  }
141
332
 
142
333
  /**
143
- * Bundle the module graph rooted at `entry` for `target`, writing a harness plus bundle to `out`.
334
+ * Bundle the module graph rooted at `entry` for `target`, writing a harness package plus bundle to
335
+ * `out`.
144
336
  * @param entry - The entry module to bundle, as a `file:` URL or path string.
145
337
  * @param target - The bundling target: a `Target` object, or a target name resolved to one (the
146
- * built-in `bare-sidecar` and `bare-worker`, or a `bare-stow-target-<name>` package).
147
- * @param out - The path to write the harness to, as a `file:` URL or path string; the bundle is
148
- * written alongside it.
338
+ * built-in `bare-kit`, `bare-sidecar`, and `bare-worker`, or a `bare-stow-target-<name>` package).
339
+ * @param out - The directory to write the harness package to, as a `file:` URL or path string.
149
340
  * @param opts - Options; see [`StowOptions`](#stowoptions).
150
- * @returns An async generator that yields each written artifact's `url` as it is produced, starting
151
- * with the harness, then the bundle, then any offloaded addon or asset files.
341
+ * @returns An async generator that yields each written artifact's `url` as it is produced: any
342
+ * addons linked into the package, the harness and its type declaration, the RPC client and its type
343
+ * declaration, the package manifest, the bundle along with its `base`, and then any assets of a
344
+ * linked bundle, any offloaded addon or asset files, and the listing of those files.
152
345
  * @throws The `target` argument is missing.
153
346
  * @throws The `out` argument is missing.
154
- * @throws A host in `opts.hosts` is not supported by the resolved target.
347
+ * @throws A language option is unknown or invalid, or `out` is not valid as a package.
348
+ * @throws The target or an RPC library does not support the language.
349
+ * @throws A host in `opts.hosts` is not supported by the resolved target in the language.
155
350
  */
156
351
  declare function stow(
157
352
  entry: URL | string,
@@ -161,15 +356,56 @@ declare function stow(
161
356
  ): AsyncGenerator<StowArtifact>
162
357
 
163
358
  declare namespace stow {
359
+ /**
360
+ * Link the addons and assets of the graphs rooted at `entries` into a package at `out`, once for
361
+ * an application. The language lays out the package and the target adds what loads the addons.
362
+ * @param entries - The entry modules of the graphs, as `file:` URLs or path strings.
363
+ * @param target - The target the graphs are stowed for, or its name.
364
+ * @param out - The directory to write the package to, as a `file:` URL or path string.
365
+ * @param opts - Options; see [`LinkOptions`](#linkoptions).
366
+ * @returns An async generator that yields the `url` of each linked addon and asset, and then of the
367
+ * module and manifest of the package.
368
+ * @throws `entries` is empty, or the `target` or `out` argument is missing.
369
+ * @throws The target does not link addons, or does not support linking for the language.
370
+ * @throws The language does not support linked addons or assets.
371
+ * @throws Two different assets would link to the same path.
372
+ */
373
+ function link(
374
+ entries: URL | string | (URL | string)[],
375
+ target: Target | TargetName,
376
+ out: URL | string,
377
+ opts?: LinkOptions
378
+ ): AsyncGenerator<StowArtifact>
379
+
380
+ /**
381
+ * The name of the folder that `stow.link()` writes the assets of the application to, which a Swift
382
+ * application copies into its bundle.
383
+ */
384
+ const resources: string
385
+
164
386
  export {
387
+ type Generated,
388
+ type Language,
389
+ type LanguageName,
390
+ type Layout,
391
+ type ManifestContext,
392
+ type LanguageOptions,
393
+ type JavaScriptOptions,
394
+ type KotlinOptions,
165
395
  type Target,
166
396
  type TargetName,
167
397
  type TargetContext,
398
+ type TargetLanguage,
399
+ type TargetResolveContext,
400
+ type TargetLinkContext,
401
+ type TargetOptions,
402
+ type Linked,
403
+ type LinkOptions,
404
+ type Resolvable,
168
405
  type RPC,
169
406
  type RPCName,
170
407
  type RPCContext,
171
- type RPCClient,
172
- type Artifact,
408
+ type RPCLanguage,
173
409
  type StowOptions,
174
410
  type StowArtifact
175
411
  }