@swiftbrowser/cli 0.1.0 → 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.
Files changed (90) hide show
  1. package/README.md +340 -65
  2. package/dist/assetSymbols.d.ts +25 -0
  3. package/dist/assetSymbols.js +218 -0
  4. package/dist/assetSymbols.js.map +1 -0
  5. package/dist/build.d.ts +27 -2
  6. package/dist/build.js +71 -14
  7. package/dist/build.js.map +1 -1
  8. package/dist/buildSettings.d.ts +15 -0
  9. package/dist/buildSettings.js +74 -0
  10. package/dist/buildSettings.js.map +1 -0
  11. package/dist/cli.d.ts +6 -0
  12. package/dist/cli.js +66 -11
  13. package/dist/cli.js.map +1 -1
  14. package/dist/commands/build.js +6 -5
  15. package/dist/commands/build.js.map +1 -1
  16. package/dist/commands/check.js +2 -2
  17. package/dist/commands/check.js.map +1 -1
  18. package/dist/commands/dev.d.ts +5 -2
  19. package/dist/commands/dev.js +19 -13
  20. package/dist/commands/dev.js.map +1 -1
  21. package/dist/commands/init.d.ts +18 -0
  22. package/dist/commands/init.js +59 -0
  23. package/dist/commands/init.js.map +1 -0
  24. package/dist/commands/kit.d.ts +3 -0
  25. package/dist/commands/kit.js +21 -0
  26. package/dist/commands/kit.js.map +1 -0
  27. package/dist/commands/shared.d.ts +28 -4
  28. package/dist/commands/shared.js +106 -11
  29. package/dist/commands/shared.js.map +1 -1
  30. package/dist/commands/test.d.ts +22 -0
  31. package/dist/commands/test.js +95 -0
  32. package/dist/commands/test.js.map +1 -0
  33. package/dist/compat.d.ts +44 -6
  34. package/dist/compat.js +64 -36
  35. package/dist/compat.js.map +1 -1
  36. package/dist/config.d.ts +48 -10
  37. package/dist/config.js +64 -8
  38. package/dist/config.js.map +1 -1
  39. package/dist/coreml.d.ts +194 -0
  40. package/dist/coreml.js +626 -0
  41. package/dist/coreml.js.map +1 -0
  42. package/dist/icu.d.ts +17 -4
  43. package/dist/icu.js +32 -18
  44. package/dist/icu.js.map +1 -1
  45. package/dist/kit.d.ts +133 -0
  46. package/dist/kit.js +403 -0
  47. package/dist/kit.js.map +1 -0
  48. package/dist/objc.d.ts +31 -0
  49. package/dist/objc.js +319 -0
  50. package/dist/objc.js.map +1 -0
  51. package/dist/packagePatches.d.ts +24 -0
  52. package/dist/packagePatches.js +107 -0
  53. package/dist/packagePatches.js.map +1 -0
  54. package/dist/packages.d.ts +59 -0
  55. package/dist/packages.js +149 -0
  56. package/dist/packages.js.map +1 -0
  57. package/dist/project.d.ts +97 -4
  58. package/dist/project.js +157 -20
  59. package/dist/project.js.map +1 -1
  60. package/dist/protobuf.d.ts +62 -0
  61. package/dist/protobuf.js +233 -0
  62. package/dist/protobuf.js.map +1 -0
  63. package/dist/stage.d.ts +175 -28
  64. package/dist/stage.js +551 -85
  65. package/dist/stage.js.map +1 -1
  66. package/dist/strings.d.ts +44 -0
  67. package/dist/strings.js +386 -0
  68. package/dist/strings.js.map +1 -0
  69. package/dist/template.d.ts +39 -0
  70. package/dist/template.js +678 -0
  71. package/dist/template.js.map +1 -0
  72. package/dist/testRunner.d.ts +1 -0
  73. package/dist/testRunner.js +44 -0
  74. package/dist/testRunner.js.map +1 -0
  75. package/dist/threadStacks.d.ts +14 -0
  76. package/dist/threadStacks.js +78 -0
  77. package/dist/threadStacks.js.map +1 -0
  78. package/dist/toolchain.d.ts +7 -1
  79. package/dist/toolchain.js +8 -2
  80. package/dist/toolchain.js.map +1 -1
  81. package/dist/urlSchemes.d.ts +11 -0
  82. package/dist/urlSchemes.js +58 -0
  83. package/dist/urlSchemes.js.map +1 -0
  84. package/dist/vendor.d.ts +109 -0
  85. package/dist/vendor.js +440 -0
  86. package/dist/vendor.js.map +1 -0
  87. package/dist/wasm.d.ts +28 -0
  88. package/dist/wasm.js +84 -0
  89. package/dist/wasm.js.map +1 -0
  90. package/package.json +7 -6
package/dist/config.d.ts CHANGED
@@ -1,5 +1,19 @@
1
- export type FoundationMode = 'lean' | 'full';
2
1
  export type SwiftLanguageMode = '5' | '6';
2
+ /**
3
+ * A Swift package the app depends on, for a folder of sources (an Xcode
4
+ * project lists its own): a remote `url` with one rule (`from`: up to the next
5
+ * major version, `exact`, `branch` or `revision`), or a local `path` (relative
6
+ * to the project), and the products the app imports.
7
+ */
8
+ export interface ConfigPackage {
9
+ url?: string;
10
+ path?: string;
11
+ from?: string;
12
+ exact?: string;
13
+ branch?: string;
14
+ revision?: string;
15
+ products: string[];
16
+ }
3
17
  export interface Config {
4
18
  /** Module name of the app (letters, digits, `_`); defaults to the target or folder name. */
5
19
  name?: string;
@@ -24,22 +38,46 @@ export interface Config {
24
38
  /** Swift language mode the sources are compiled in (default 5, like Xcode's default for apps). */
25
39
  swiftLanguageMode?: SwiftLanguageMode;
26
40
  /**
27
- * `full` (default): the wasm SDK's Foundation, nothing rewritten, its ICU
28
- * data trimmed to `locales` (see below); about 19 MB optimized, 6.6 MB
29
- * gzipped. `lean`: `import Foundation` is rewritten to FoundationEssentials
30
- * + FoundationLite, a smaller module (4.5 to 9 MB) with a smaller API.
41
+ * The languages whose ICU locale data stays in the module (`["en"]` by
42
+ * default; `["*"]` keeps everything). The viewer's language is chosen among
43
+ * them at launch. Each language adds roughly 100 to 300 kB, Chinese 1.7 MB.
31
44
  */
32
- foundation?: FoundationMode;
45
+ locales?: string[];
33
46
  /**
34
- * In full mode, the languages whose ICU locale data is kept (BCP 47 tags;
35
- * the region part is ignored, every regional variant of the language stays).
36
- * Default `["en"]`, about 5.5 MB; `["*"]` keeps the SDK's whole 34 MB.
47
+ * Whether ICU's collation tables ship (default true). `false` saves 0.9 MB
48
+ * when the app never compares strings in a locale (`localizedCompare`,
49
+ * `localizedStandardCompare`, `.localizedStandard` sorting fall back to
50
+ * Unicode scalar order).
37
51
  */
38
- locales?: string[];
52
+ collation?: boolean;
39
53
  /** Extra `-D` compilation conditions (SWIFTBROWSER is always defined). */
40
54
  defines?: string[];
55
+ /**
56
+ * The app's URL schemes, whose OAuth redirects come back through the page
57
+ * (docs/ops-protocol.md, "Signing in"); replaces those of the Info.plist's
58
+ * `CFBundleURLTypes`.
59
+ */
60
+ urlSchemes?: string[];
61
+ /**
62
+ * A CORS proxy (packages/cors-proxy, deployed on Cloudflare): the page
63
+ * retries a cross-origin GET or HEAD the browser refused through
64
+ * `<corsProxy>?url=<target>`. For apps whose servers do not allow the page's
65
+ * origin (images, mostly), as in screenshots and demos. `--cors-proxy`
66
+ * overrides it.
67
+ */
68
+ corsProxy?: string;
69
+ /**
70
+ * Hosts (and their subdomains) the app's requests may not reach in the
71
+ * browser: they fail as a network error does. For a public deploy of an app
72
+ * whose analytics belong to someone else. `--block-host` adds to them.
73
+ */
74
+ blockHosts?: string[];
75
+ /** Swift packages the app depends on, added to the Xcode target's (see `ConfigPackage`). */
76
+ packages?: ConfigPackage[];
41
77
  }
42
78
  export declare const CONFIG_FILE = "swiftbrowser.json";
43
79
  /** Reads and validates `swiftbrowser.json` in `dir` (or the file at `file`); `{}` when absent. */
44
80
  export declare function loadConfig(dir: string, file?: string): Config;
45
81
  export declare function validateConfig(raw: unknown, source?: string): Config;
82
+ /** Whether `value` is an absolute http(s) URL (a CORS proxy's). */
83
+ export declare function isHTTPURL(value: string): boolean;
package/dist/config.js CHANGED
@@ -3,10 +3,10 @@
3
3
  // need no file at all.
4
4
  import { existsSync, readFileSync } from 'node:fs';
5
5
  import path from 'node:path';
6
- import { CliError } from './log.js';
6
+ import { CliError, info, warn } from './log.js';
7
7
  export const CONFIG_FILE = 'swiftbrowser.json';
8
- const STRING_KEYS = ['name', 'displayName', 'target', 'icon'];
9
- const LIST_KEYS = ['sources', 'exclude', 'catalogs', 'resources', 'defines', 'locales'];
8
+ const STRING_KEYS = ['name', 'displayName', 'target', 'icon', 'corsProxy'];
9
+ const LIST_KEYS = ['sources', 'exclude', 'catalogs', 'resources', 'defines', 'locales', 'urlSchemes', 'blockHosts'];
10
10
  /** Reads and validates `swiftbrowser.json` in `dir` (or the file at `file`); `{}` when absent. */
11
11
  export function loadConfig(dir, file) {
12
12
  const configPath = file ?? path.join(dir, CONFIG_FILE);
@@ -45,26 +45,82 @@ export function validateConfig(raw, source = CONFIG_FILE) {
45
45
  throw new CliError(`${source}: "${key}" must be an array of strings`);
46
46
  config[key] = value;
47
47
  }
48
+ if (record['collation'] !== undefined) {
49
+ if (typeof record['collation'] !== 'boolean')
50
+ throw new CliError(`${source}: "collation" must be true or false`);
51
+ config.collation = record['collation'];
52
+ }
48
53
  if (record['swiftLanguageMode'] !== undefined) {
49
54
  const mode = String(record['swiftLanguageMode']);
50
55
  if (mode !== '5' && mode !== '6')
51
56
  throw new CliError(`${source}: "swiftLanguageMode" must be "5" or "6"`);
52
57
  config.swiftLanguageMode = mode;
53
58
  }
59
+ if (record['packages'] !== undefined)
60
+ config.packages = validatePackages(record['packages'], source);
54
61
  if (record['foundation'] !== undefined) {
55
- const mode = record['foundation'];
56
- if (mode !== 'lean' && mode !== 'full')
57
- throw new CliError(`${source}: "foundation" must be "lean" or "full"`);
58
- config.foundation = mode;
62
+ // Phase 14: there is one Foundation now. Old files may still say "lean" or "full".
63
+ info(warn(`${source}: "foundation" is ignored; the real Foundation is always used (lean mode was removed)`));
64
+ }
65
+ if (config.corsProxy !== undefined && !isHTTPURL(config.corsProxy)) {
66
+ throw new CliError(`${source}: "corsProxy" must be an http(s) URL`);
59
67
  }
60
68
  if (config.name !== undefined && !/^[A-Za-z_][A-Za-z0-9_]*$/.test(config.name)) {
61
69
  throw new CliError(`${source}: "name" must be a Swift module name (letters, digits, underscores)`);
62
70
  }
63
71
  for (const key of Object.keys(record)) {
64
- if (!STRING_KEYS.includes(key) && !LIST_KEYS.includes(key) && key !== 'swiftLanguageMode' && key !== 'foundation' && key !== '$schema') {
72
+ if (!STRING_KEYS.includes(key) && !LIST_KEYS.includes(key) && key !== 'swiftLanguageMode' && key !== 'collation' && key !== 'packages' && key !== 'foundation' && key !== '$schema') {
65
73
  throw new CliError(`${source}: unknown key "${key}"`);
66
74
  }
67
75
  }
68
76
  return config;
69
77
  }
78
+ const PACKAGE_KEYS = ['url', 'path', 'from', 'exact', 'branch', 'revision'];
79
+ const PACKAGE_RULES = ['from', 'exact', 'branch', 'revision'];
80
+ function validatePackages(value, source) {
81
+ if (!Array.isArray(value))
82
+ throw new CliError(`${source}: "packages" must be an array`);
83
+ return value.map((entry, index) => {
84
+ const where = `${source}: packages[${index}]`;
85
+ if (typeof entry !== 'object' || entry === null || Array.isArray(entry))
86
+ throw new CliError(`${where} must be an object`);
87
+ const record = entry;
88
+ const pkg = { products: [] };
89
+ for (const key of Object.keys(record)) {
90
+ if (!PACKAGE_KEYS.includes(key) && key !== 'products')
91
+ throw new CliError(`${where}: unknown key "${key}"`);
92
+ }
93
+ for (const key of PACKAGE_KEYS) {
94
+ const field = record[key];
95
+ if (field === undefined)
96
+ continue;
97
+ if (typeof field !== 'string' || field === '')
98
+ throw new CliError(`${where}: "${key}" must be a string`);
99
+ pkg[key] = field;
100
+ }
101
+ const products = record['products'];
102
+ if (!Array.isArray(products) || products.length === 0 || !products.every((p) => typeof p === 'string')) {
103
+ throw new CliError(`${where}: "products" must be a non-empty array of strings`);
104
+ }
105
+ pkg.products = products;
106
+ if (!pkg.url === !pkg.path)
107
+ throw new CliError(`${where}: give either "url" or "path"`);
108
+ const rules = PACKAGE_RULES.filter((key) => pkg[key] !== undefined);
109
+ if (pkg.url && rules.length !== 1)
110
+ throw new CliError(`${where}: a "url" needs one of "from", "exact", "branch" or "revision"`);
111
+ if (pkg.path && rules.length > 0)
112
+ throw new CliError(`${where}: a "path" takes no version rule`);
113
+ return pkg;
114
+ });
115
+ }
116
+ /** Whether `value` is an absolute http(s) URL (a CORS proxy's). */
117
+ export function isHTTPURL(value) {
118
+ try {
119
+ const url = new URL(value);
120
+ return url.protocol === 'http:' || url.protocol === 'https:';
121
+ }
122
+ catch {
123
+ return false;
124
+ }
125
+ }
70
126
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,194 @@
1
+ import { CliError } from './log.js';
2
+ export type ArrayDataType = 'double' | 'float32' | 'float16' | 'int32' | 'int8';
3
+ export type FeatureType = {
4
+ type: 'int64';
5
+ } | {
6
+ type: 'double';
7
+ } | {
8
+ type: 'string';
9
+ } | {
10
+ type: 'multiArray';
11
+ shape: number[];
12
+ dataType: ArrayDataType;
13
+ } | {
14
+ type: 'dictionary';
15
+ keyType: 'int64' | 'string';
16
+ };
17
+ export type FeatureDescription = FeatureType & {
18
+ name: string;
19
+ optional?: true;
20
+ /** The feature's description in the model; a doc comment in the generated code, not part of the JSON. */
21
+ shortDescription?: string;
22
+ };
23
+ export interface ModelMetadata {
24
+ shortDescription?: string;
25
+ versionString?: string;
26
+ author?: string;
27
+ license?: string;
28
+ creatorDefined?: Record<string, string>;
29
+ }
30
+ export interface ModelDescription {
31
+ inputs: FeatureDescription[];
32
+ outputs: FeatureDescription[];
33
+ predictedFeatureName?: string;
34
+ predictedProbabilitiesName?: string;
35
+ metadata?: ModelMetadata;
36
+ }
37
+ export type ClassLabels = {
38
+ strings: string[];
39
+ } | {
40
+ int64s: number[];
41
+ };
42
+ /**
43
+ * One tree of an ensemble, its nodes in columns, the root first. Children
44
+ * are positions in these arrays (-1 for a leaf); a leaf's values are
45
+ * `leafIndices` / `leafValues` from `leafStarts[node]` up to `leafStarts[node + 1]`.
46
+ */
47
+ export interface Tree {
48
+ /** TreeNodeBehavior: 0 ≤, 1 <, 2 ≥, 3 >, 4 ==, 5 ≠ (branches), 6 leaf. */
49
+ behaviors: number[];
50
+ features: number[];
51
+ thresholds: number[];
52
+ trueChildren: number[];
53
+ falseChildren: number[];
54
+ /** Whether a missing value (NaN) takes the true branch. */
55
+ missingTrue: boolean[];
56
+ leafStarts: number[];
57
+ leafIndices: number[];
58
+ leafValues: number[];
59
+ }
60
+ export type TreeTransform = 'none' | 'softmax' | 'logistic' | 'softmaxWithZeroClassReference';
61
+ export interface TreeEnsemble {
62
+ dimensions: number;
63
+ base: number[];
64
+ trees: Tree[];
65
+ transform: TreeTransform;
66
+ }
67
+ export type ImputedValue = {
68
+ double: number;
69
+ } | {
70
+ int64: number;
71
+ } | {
72
+ string: string;
73
+ } | {
74
+ doubles: number[];
75
+ } | {
76
+ int64s: number[];
77
+ } | {
78
+ stringDictionary: Record<string, number>;
79
+ }
80
+ /** Keys are the int64 keys in decimal (JSON object keys are strings). */
81
+ | {
82
+ int64Dictionary: Record<string, number>;
83
+ };
84
+ export type ReplaceValue = {
85
+ double: number;
86
+ } | {
87
+ int64: number;
88
+ } | {
89
+ string: string;
90
+ };
91
+ export type ModelKind = {
92
+ kind: 'pipeline' | 'pipelineClassifier' | 'pipelineRegressor';
93
+ models: ModelSpec[];
94
+ } | {
95
+ kind: 'glmRegressor';
96
+ weights: number[][];
97
+ offsets: number[];
98
+ transform: 'none' | 'logit' | 'probit';
99
+ } | {
100
+ kind: 'glmClassifier';
101
+ weights: number[][];
102
+ offsets: number[];
103
+ transform: 'logit' | 'probit';
104
+ encoding: 'referenceClass' | 'oneVsRest';
105
+ labels: ClassLabels;
106
+ } | ({
107
+ kind: 'treeEnsembleRegressor';
108
+ } & TreeEnsemble) | ({
109
+ kind: 'treeEnsembleClassifier';
110
+ labels: ClassLabels;
111
+ } & TreeEnsemble) | {
112
+ kind: 'featureVectorizer';
113
+ columns: {
114
+ name: string;
115
+ dimensions: number;
116
+ }[];
117
+ } | {
118
+ kind: 'oneHotEncoder';
119
+ categories: ClassLabels;
120
+ sparse: boolean;
121
+ ignoreUnknown: boolean;
122
+ } | {
123
+ kind: 'normalizer';
124
+ norm: 'max' | 'l1' | 'l2';
125
+ } | {
126
+ kind: 'imputer';
127
+ imputed: ImputedValue;
128
+ replace?: ReplaceValue;
129
+ } | {
130
+ kind: 'scaler';
131
+ shift: number[];
132
+ scale: number[];
133
+ } | {
134
+ kind: 'dictVectorizer';
135
+ keys: ClassLabels;
136
+ } | {
137
+ kind: 'arrayFeatureExtractor';
138
+ indices: number[];
139
+ } | {
140
+ kind: 'categoricalMapping';
141
+ stringToInt64?: Record<string, number>;
142
+ int64ToString?: Record<string, string>;
143
+ defaultString?: string;
144
+ defaultInt64?: number;
145
+ } | {
146
+ kind: 'identity';
147
+ };
148
+ export interface ModelSpec {
149
+ specificationVersion: number;
150
+ description: ModelDescription;
151
+ model: ModelKind;
152
+ }
153
+ export declare const SUPPORTED_SUMMARY = "linear and logistic regression (GLM), boosted trees and random forests (tree ensembles), and pipelines of them with feature vectorizers, one-hot encoders, imputers, normalizers, scalers and the other feature-engineering models";
154
+ /** A model the CLI cannot compile: names the file and what is wrong. */
155
+ export declare class ModelError extends CliError {
156
+ }
157
+ /** Parses a model's protobuf bytes; `file` names it in errors. */
158
+ export declare function parseModel(bytes: Uint8Array, file: string): ModelSpec;
159
+ /**
160
+ * The protobuf of an `.mlmodel` file, or of the root model of an `.mlpackage`
161
+ * (its Manifest.json names the specification file under Data/).
162
+ */
163
+ export declare function readModelBytes(file: string): Uint8Array;
164
+ /** The class Xcode generates for `file`: its base name as a Swift identifier. */
165
+ export declare function modelClassName(file: string): string;
166
+ /** A feature name as a Swift identifier, as Xcode spells it: other characters become `_`, keywords get backticks. */
167
+ export declare function swiftIdentifier(name: string): string;
168
+ /** The Swift type Xcode gives a feature. */
169
+ export declare function swiftType(feature: FeatureType): string;
170
+ /**
171
+ * The spec as JSON for the generated file: objects one key per line (a short
172
+ * one whose values are all numbers, strings or lists of them on one line),
173
+ * lists of numbers and strings on one line, NaN and infinities as the strings
174
+ * the CoreML module's decoder converts back ("nan", "inf", "-inf").
175
+ */
176
+ export declare function specJSON(value: unknown, indent?: string): string;
177
+ /**
178
+ * The Swift Xcode would generate for the model, with the model itself
179
+ * embedded: the class with `model: MLModel`, `urlOfModelInThisBundle`, the
180
+ * initializers and `load` functions, `prediction` with one argument per input
181
+ * and with an `Input`, `predictions(inputs:)`; the Input and Output feature
182
+ * providers. `file` is the model's path (for the header comment).
183
+ */
184
+ export declare function generateModelSource(className: string, spec: ModelSpec, file: string): string;
185
+ export interface CompiledModel {
186
+ /** The model file (`.mlmodel`) or package (`.mlpackage`). */
187
+ file: string;
188
+ className: string;
189
+ spec: ModelSpec;
190
+ /** The generated Swift. */
191
+ source: string;
192
+ }
193
+ /** Reads, checks and generates the Swift for one model. */
194
+ export declare function compileModel(file: string): CompiledModel;