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