@blotch/rsbuild-plugin-angular-lynx 0.0.0-stage → 22.2.1

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 (76) hide show
  1. package/README.md +37 -2
  2. package/dist/angular-rebuild-coordinator.d.ts +70 -0
  3. package/dist/angular-rebuild-coordinator.test.d.ts +1 -0
  4. package/dist/angular-webpack-plugin.d.ts +127 -0
  5. package/dist/angular-webpack-plugin.test.d.ts +1 -0
  6. package/dist/angular.d.ts +31 -0
  7. package/dist/build-schema-source-file-cache.d.ts +20 -0
  8. package/dist/build-schema-source-file-cache.test.d.ts +1 -0
  9. package/dist/component-styles-cache.d.ts +43 -0
  10. package/dist/component-styles-cache.test.d.ts +1 -0
  11. package/dist/css.d.ts +13 -0
  12. package/dist/css.test.d.ts +1 -0
  13. package/dist/entry.d.ts +11 -0
  14. package/dist/entry.test.d.ts +1 -0
  15. package/dist/generator.d.ts +2 -0
  16. package/dist/generator.test.d.ts +1 -0
  17. package/dist/index.d.ts +1 -0
  18. package/dist/index.js +1510 -0
  19. package/dist/index.js.LICENSE.txt +7 -0
  20. package/dist/is-lynx-unknown-element-message.d.ts +12 -0
  21. package/dist/is-lynx-unknown-element-message.test.d.ts +1 -0
  22. package/dist/layers.d.ts +12 -0
  23. package/dist/layers.test.d.ts +1 -0
  24. package/dist/loaders/ignore-css-loader.d.ts +7 -0
  25. package/dist/loaders/ignore-css-loader.js +7 -0
  26. package/dist/loaders/ignore-css-loader.test.d.ts +1 -0
  27. package/dist/loaders/thread-globals-loader.d.ts +8 -0
  28. package/dist/loaders/thread-globals-loader.js +6 -0
  29. package/dist/loaders/thread-globals-loader.test.d.ts +1 -0
  30. package/dist/logger/dev-logger-middleware.d.ts +12 -0
  31. package/dist/logger/dev-logger-middleware.test.d.ts +1 -0
  32. package/dist/logger/dev-logger.d.ts +2 -0
  33. package/dist/logger/dev-logger.test.d.ts +1 -0
  34. package/dist/lynx-diagnostics.d.ts +38 -0
  35. package/dist/lynx-diagnostics.test.d.ts +1 -0
  36. package/dist/lynx-process-eval-result-runtime-module.d.ts +21 -0
  37. package/dist/lynx-process-eval-result-runtime-module.test.d.ts +1 -0
  38. package/dist/plugin-angular-lynx.d.ts +3 -0
  39. package/dist/plugin-angular-lynx.test.d.ts +1 -0
  40. package/dist/polyfills.js +122 -0
  41. package/dist/seed-compilation-source-files.d.ts +22 -0
  42. package/dist/seed-compilation-source-files.test.d.ts +1 -0
  43. package/dist/split-chunks.d.ts +3 -0
  44. package/dist/split-chunks.test.d.ts +1 -0
  45. package/dist/tailwind.d.ts +2 -0
  46. package/dist/tailwind.test.d.ts +1 -0
  47. package/dist/transform-module.d.ts +31 -0
  48. package/dist/transform-module.test.d.ts +1 -0
  49. package/dist/utils/angular/angular-config.d.ts +3 -0
  50. package/dist/utils/angular/angular-config.test.d.ts +1 -0
  51. package/dist/utils/angular/component-scope-id.d.ts +12 -0
  52. package/dist/utils/angular/component-scope-id.test.d.ts +1 -0
  53. package/dist/utils/angular/component-style-bundler.d.ts +19 -0
  54. package/dist/utils/angular/component-style-bundler.test.d.ts +1 -0
  55. package/dist/utils/angular/env.d.ts +2 -0
  56. package/dist/utils/angular/env.test.d.ts +1 -0
  57. package/dist/utils/angular/find-up.d.ts +8 -0
  58. package/dist/utils/angular/find-up.test.d.ts +1 -0
  59. package/dist/utils/angular/normalize-cache.d.ts +22 -0
  60. package/dist/utils/angular/normalize-cache.test.d.ts +1 -0
  61. package/dist/utils/angular/options.d.ts +82 -0
  62. package/dist/utils/angular/options.test.d.ts +1 -0
  63. package/dist/utils/angular/read-workspace.d.ts +7 -0
  64. package/dist/utils/angular/read-workspace.test.d.ts +1 -0
  65. package/dist/utils/angular/resolve-pages.d.ts +13 -0
  66. package/dist/utils/angular/resolve-pages.test.d.ts +1 -0
  67. package/dist/utils/inject-lynx-schema.d.ts +10 -0
  68. package/dist/utils/inject-lynx-schema.test.d.ts +1 -0
  69. package/dist/utils/options.d.ts +31 -0
  70. package/dist/utils/options.test.d.ts +1 -0
  71. package/dist/utils/strip-template-whitespace.d.ts +34 -0
  72. package/dist/utils/strip-template-whitespace.test.d.ts +1 -0
  73. package/dist/worklet-transform.d.ts +7 -0
  74. package/dist/worklet-transform.test.d.ts +1 -0
  75. package/package.json +73 -4
  76. package/patch/patch-angular-build.cjs +27 -0
package/README.md CHANGED
@@ -1,3 +1,38 @@
1
- # Temporary Holding Version
1
+ # @blotch/rsbuild-plugin-angular-lynx
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Rsbuild plugin that compiles Angular apps for the [Lynx](https://lynxjs.org/) native runtime. Produces dual-thread bundles (main + background) for iOS, Android, and Web.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @blotch/rsbuild-plugin-angular-lynx
9
+ ```
10
+
11
+ > Starting a new project? `ng add @blotch/angular-lynx` sets this up automatically.
12
+
13
+ ## Usage
14
+
15
+ Add the plugin to your `lynx.config.ts`:
16
+
17
+ ```typescript
18
+ import { pluginAngularLynx } from '@blotch/rsbuild-plugin-angular-lynx';
19
+ import { defineConfig } from '@lynx-js/rspeedy';
20
+
21
+ export default defineConfig({
22
+ source: {
23
+ entry: './src/main.ts',
24
+ },
25
+ plugins: [pluginAngularLynx()],
26
+ });
27
+ ```
28
+
29
+ ## What It Does
30
+
31
+ - Runs Angular's AOT compiler within Rsbuild/webpack
32
+ - Splits each entry into **main-thread** and **background-thread** bundles for Lynx's dual-thread model
33
+ - Bundles component stylesheets and processes CSS
34
+ - Registers `CUSTOM_ELEMENTS_SCHEMA` so Angular accepts Lynx elements (`<view>`, `<text>`, etc.)
35
+
36
+ ## Documentation
37
+
38
+ Full docs at [angularlynx.dev](https://angularlynx.dev).
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Identifies one on-disk version of a file: its mtime, or `null` when the file
3
+ * doesn't exist (it was deleted).
4
+ */
5
+ export type FileVersion = number | null;
6
+ /**
7
+ * What one Angular compile reports back to the coordinator.
8
+ */
9
+ export type AngularCompileResult = {
10
+ /**
11
+ * Files whose compiled output changed during this compile: re-emitted
12
+ * TypeScript modules whose JS differs from the cached copy, and any scoped
13
+ * stylesheets rewritten on disk. rspack must rebuild these even when their
14
+ * own source didn't change (e.g. a parent component whose template
15
+ * compilation depends on an edited child component).
16
+ */
17
+ changedOutputs: Iterable<string>;
18
+ /**
19
+ * Every file the compilation read: program sources plus component
20
+ * resources such as external templates and stylesheets. Changes to any
21
+ * other non-TypeScript file (global CSS, assets, the scoped-CSS cache this
22
+ * plugin writes itself) can't affect Angular's output, so they don't
23
+ * trigger a recompile.
24
+ */
25
+ inputFiles: Iterable<string>;
26
+ };
27
+ export type AngularRebuildCoordinator = {
28
+ /**
29
+ * Brings the shared Angular compilation up to date before one environment's
30
+ * rspack compile.
31
+ *
32
+ * @param environmentName - the rsbuild environment about to compile.
33
+ * @param changedFiles - files the environment's watcher reported as modified
34
+ * or removed since its previous compile (empty for its first compile).
35
+ * @returns files whose compiled output changed since this environment last
36
+ * compiled. The caller adds them to the rspack compiler's
37
+ * `modifiedFiles` so rspack re-runs the loader for those modules.
38
+ */
39
+ prepare: (environmentName: string, changedFiles: Iterable<string>) => Promise<Set<string>>;
40
+ };
41
+ /**
42
+ * Keeps one Angular compilation in sync with rspack's watch rebuilds.
43
+ *
44
+ * Angular compiles the whole program up front and the rspack loader only
45
+ * serves its cached output. So on every rebuild, Angular has to recompile the
46
+ * changed files *before* rspack re-runs the loader. Otherwise the loader
47
+ * serves the previous output and the dev server ships an empty hot update.
48
+ *
49
+ * Two things make this more than "recompile on every watchRun":
50
+ *
51
+ * - **Several environments share one compilation.** `rspeedy dev` builds `web`
52
+ * and `lynx` with separate rspack compilers. Each compiler's watcher reports
53
+ * the same edit, and rsbuild runs their before-compile hooks concurrently.
54
+ * Compiles are therefore serialized (two concurrent `initialize()` calls on
55
+ * one compilation would corrupt it). A file version Angular has already seen
56
+ * doesn't trigger a second compile; only versions it hasn't seen do.
57
+ * - **rspack only rebuilds modules whose files changed.** When an edit changes
58
+ * the compiled output of another file, that file's module would keep its
59
+ * stale output. So each compile reports which outputs changed, and every
60
+ * environment gets back the ones it hasn't rebuilt yet.
61
+ */
62
+ export declare const createAngularRebuildCoordinator: ({ compile, getFileVersion, }: {
63
+ /**
64
+ * Runs one Angular compile. `changedFiles` is `undefined` for the initial
65
+ * full compile and lists the changed inputs for incremental ones.
66
+ */
67
+ compile: (changedFiles: ReadonlySet<string> | undefined) => Promise<AngularCompileResult>;
68
+ /** Injectable for tests; defaults to the file's mtime. */
69
+ getFileVersion?: (file: string) => FileVersion;
70
+ }) => AngularRebuildCoordinator;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,127 @@
1
+ import type { Compiler } from '@rspack/core';
2
+ /**
3
+ * The options for extractStr.
4
+ *
5
+ * @public
6
+ */
7
+ export type ExtractStrConfig = {
8
+ /**
9
+ * The minimum length of string literals to be extracted.
10
+ *
11
+ * @defaultValue `20`
12
+ *
13
+ * @public
14
+ */
15
+ strLength: number;
16
+ /**
17
+ * @internal
18
+ */
19
+ extractedStrArr?: string[];
20
+ };
21
+ /**
22
+ * The options for AngularWebpackPluginOptions
23
+ *
24
+ * @public
25
+ */
26
+ type AngularWebpackPluginOptions = {
27
+ /**
28
+ * Whether to disable warnings about incompatible createSelectorQuery usage
29
+ */
30
+ disableCreateSelectorQueryIncompatibleWarning?: boolean | undefined;
31
+ /**
32
+ * When to sync the first screen content
33
+ */
34
+ firstScreenSyncTiming?: 'immediately' | 'jsReady';
35
+ /**
36
+ * Whether to enable server-side rendering
37
+ */
38
+ enableSSR?: boolean;
39
+ /**
40
+ * Whether this bundle targets the web runtime (`@lynx-js/web-core`) rather
41
+ * than native Lynx. Injected into the bundle as the `__WEB__` compile-time
42
+ * define so the runtime can branch on web-only behavior (e.g. forcing the
43
+ * first element-tree flush, which native does implicitly but web-core does
44
+ * not). Set from `environment.name === 'web'` in entry.ts.
45
+ */
46
+ isWeb?: boolean;
47
+ /**
48
+ * The chunk names to be considered as main thread chunks.
49
+ */
50
+ mainThreadChunks?: string[] | undefined;
51
+ /**
52
+ * Merge same string literals in JS and Lepus to reduce output bundle size.
53
+ * Set to `false` to disable.
54
+ *
55
+ * @defaultValue false
56
+ */
57
+ extractStr?: Partial<ExtractStrConfig> | boolean;
58
+ /**
59
+ * Whether to enable lazy bundle.
60
+ *
61
+ * @alpha
62
+ */
63
+ experimental_isLazyBundle?: boolean;
64
+ };
65
+ /**
66
+ * AngularWebpackPlugin allows using Angular with Lynx and webpack
67
+ *
68
+ * @example
69
+ * ```js
70
+ * // webpack.config.js
71
+ * import { AngularWebpackPlugin } from '@lynx-js/angular-webpack-plugin'
72
+ * export default {
73
+ * plugins: [new AngularWebpackPlugin()],
74
+ * }
75
+ * ```
76
+ *
77
+ * @public
78
+ */
79
+ declare class AngularWebpackPlugin {
80
+ #private;
81
+ /**
82
+ * The loaders for Angular with Lynx.
83
+ *
84
+ * @remarks
85
+ * Note that this loader will only transform TypeScript to valid JavaScript.
86
+ * You should use `swc-loader` to load TypeScript files.
87
+ *
88
+ * @example
89
+ * ```js
90
+ * // webpack.config.js
91
+ * import { AngularWebpackPlugin, LAYERS } from '@lynx-js/angular-webpack-plugin'
92
+ * export default {
93
+ * module: {
94
+ * rules: [
95
+ * {
96
+ * test: /\.ts$/,
97
+ * layer: LAYERS.MAIN_THREAD,
98
+ * use: ['swc-loader', AngularWebpackPlugin.loaders.MAIN_THREAD]
99
+ * },
100
+ * {
101
+ * test: /\.ts$/,
102
+ * layer: LAYERS.BACKGROUND,
103
+ * use: ['swc-loader', AngularWebpackPlugin.loaders.BACKGROUND]
104
+ * },
105
+ * ],
106
+ * },
107
+ * plugins: [new AngularWebpackPlugin()],
108
+ * }
109
+ * ```
110
+ *
111
+ * @public
112
+ */ options: AngularWebpackPluginOptions | undefined;
113
+ constructor(options?: AngularWebpackPluginOptions | undefined);
114
+ /**
115
+ * `defaultOptions` is the default options that the {@link AngularWebpackPlugin} uses.
116
+ *
117
+ * @public
118
+ */
119
+ static defaultOptions: Readonly<Required<AngularWebpackPluginOptions>>;
120
+ /**
121
+ * The entry point of a webpack plugin.
122
+ * @param compiler - the webpack compiler
123
+ */
124
+ apply(compiler: Compiler): void;
125
+ }
126
+ export type { AngularWebpackPluginOptions };
127
+ export { AngularWebpackPlugin };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ import type { RsbuildPluginAPI } from '@lynx-js/rspeedy';
2
+ import type { PluginAngularLynxOptions } from './utils/options.js';
3
+ /**
4
+ * Wires Angular's AOT/JIT compilation pipeline into the rsbuild/rspack build
5
+ * graph. This is the heart of the AngularLynx build — it bridges three worlds:
6
+ *
7
+ * 1. **Angular's compiler** (`@angular/build`) — runs `createAngularCompilation`
8
+ * to type-check templates, transform component metadata, and emit JS+CSS.
9
+ * 2. **Lynx's native element model** — Angular's template type-checker has
10
+ * no knowledge of `<view>`, `<text>`, `<scroll-view>`, etc., so we inject
11
+ * CUSTOM_ELEMENTS_SCHEMA into every @Component-bearing source file before
12
+ * Angular's compiler sees it (see build-schema-source-file-cache.ts).
13
+ * 3. **rspack's loader pipeline** — Angular emits transformed output into a
14
+ * `typeScriptFileCache`; the `api.transform()` hook below intercepts every
15
+ * `.ts`/`.js` request and serves the precompiled content instead of
16
+ * letting rspack try to parse the original TypeScript.
17
+ *
18
+ * The flow runs before every environment build, including watch rebuilds:
19
+ * onBeforeEnvironmentCompile → angular-rebuild-coordinator (dedupe + serialize)
20
+ * → buildLynxSchemaSourceFileCache (schema inject)
21
+ * → compilation.update (rebuilds only: invalidate the changed files)
22
+ * → compilation.initialize (Angular AOT walk + transformStylesheet callback)
23
+ * → emitAffectedFiles (refreshes typeScriptFileCache)
24
+ * → diagnoseFiles (filtered to suppress Lynx-element false positives)
25
+ * → rspack rebuilds the changed files plus any whose compiled output changed
26
+ *
27
+ * Then for each module request the `api.transform` hook delegates the per-module
28
+ * string transform (import-prepend + ɵcmp.id + worklet) to
29
+ * `buildTransformedCode` in transform-module.ts.
30
+ */
31
+ export declare const applyAngularRules: (api: RsbuildPluginAPI, pluginOptions: Required<PluginAngularLynxOptions>) => Promise<void>;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Reads the tsconfig to enumerate all project TypeScript files, then returns a
3
+ * Map<filePath, SourceFile> where every file containing an @Component decorator
4
+ * has had CUSTOM_ELEMENTS_SCHEMA injected. Angular's compiler host checks this
5
+ * cache before reading from disk, so the template type-checker never sees unknown
6
+ * Lynx element errors without the user having to add the schema manually.
7
+ *
8
+ * Returns Map<string, any> to avoid TypeScript instance mismatch: the plugin's
9
+ * local `typescript` package and `@angular/build`'s TypeScript resolve to different
10
+ * module instances in the monorepo, making their SourceFile types structurally
11
+ * incompatible at the type level even though they're identical at runtime.
12
+ *
13
+ * `shouldInclude` limits which files are read and parsed; `fileNames` still lists
14
+ * every project file. Watch rebuilds pass it so only changed and new files are
15
+ * re-parsed, instead of every component in the project on each save.
16
+ */
17
+ export declare const buildLynxSchemaSourceFileCache: (tsconfig: string, shouldInclude?: (filePath: string) => boolean) => {
18
+ sourceFileCache: Map<string, any>;
19
+ fileNames: string[];
20
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Per-component stylesheet bookkeeping. `imports` lists the on-disk scoped CSS
3
+ * paths the loader will prepend as `import` statements; `inlineStyles` mirrors
4
+ * Angular's inline-style handling surface; `processedFiles` deduplicates calls
5
+ * that Angular's AOT compiler makes multiple times for the same stylesheet.
6
+ */
7
+ export type ComponentStylesEntry = {
8
+ imports: string[];
9
+ inlineStyles: string[];
10
+ scopeId: string;
11
+ processedFiles: Map<string, string>;
12
+ };
13
+ export type ComponentScopeInfo = {
14
+ className: string;
15
+ scopeId: string;
16
+ };
17
+ /**
18
+ * Builds the `transformStylesheet` callback that Angular's AOT compiler invokes
19
+ * for every component stylesheet (inline `styles: []` and external `styleUrls`).
20
+ *
21
+ * The callback is a closure over the two shared caches the loader
22
+ * (`api.transform` in angular.ts) later reads from:
23
+ * - `componentStylesCache` — maps component source file → its scoped CSS imports
24
+ * - `componentScopeIds` — maps component source file → { className, scopeId }
25
+ *
26
+ * Extracted from angular.ts so the dedup / scoped-path / write-if-changed logic
27
+ * can be unit-tested directly by driving the returned callback, without standing
28
+ * up a full Angular compilation.
29
+ */
30
+ export declare const createTransformStylesheet: (params: {
31
+ basePath: string;
32
+ scopedCssCacheDir: string;
33
+ componentStylesCache: Map<string, ComponentStylesEntry>;
34
+ componentScopeIds: Map<string, ComponentScopeInfo>;
35
+ /**
36
+ * Called with the path of each scoped CSS file whose contents were
37
+ * (re)written. On watch rebuilds the scoped files change after rspack's
38
+ * watcher has already collected the edit, so angular.ts passes them to
39
+ * rspack as modified. Otherwise the CSS change would only ship on the
40
+ * following rebuild.
41
+ */
42
+ onStylesheetWritten?: (filePath: string) => void;
43
+ }) => ((data: string, containingFile: string, stylesheetFile: string | undefined, order: number, className: string | undefined) => Promise<string>);
@@ -0,0 +1 @@
1
+ export {};
package/dist/css.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import type { RsbuildPluginAPI } from '@lynx-js/rspeedy';
2
+ import type { CSSLoaderOptions } from '@rsbuild/core';
3
+ import type { PluginAngularLynxOptions } from './utils/options.js';
4
+ export declare const applyCSS: (api: RsbuildPluginAPI, options: Required<PluginAngularLynxOptions>) => void;
5
+ /**
6
+ * This is copied from https://github.com/web-infra-dev/rsbuild/blob/9f8be2d71ffeb7da969cda36fd9755db2cadaff5/packages/core/src/plugins/css.ts#L42
7
+ *
8
+ * If the target is not `web` and the modules option of css-loader is enabled,
9
+ * we must enable exportOnlyLocals to only exports the modules identifier mappings.
10
+ * Otherwise, the compiled CSS code may contain invalid code, such as `new URL`.
11
+ * https://github.com/webpack-contrib/css-loader#exportonlylocals
12
+ */
13
+ export declare const normalizeCssLoaderOptions: (options: CSSLoaderOptions, exportOnlyLocals: boolean) => CSSLoaderOptions;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import type { RsbuildPluginAPI, Rspack } from '@lynx-js/rspeedy';
2
+ import type { UndefinedOnPartialDeep } from 'type-fest';
3
+ import type { PluginAngularLynxOptions } from './utils/options.js';
4
+ export declare const applyEntry: (api: RsbuildPluginAPI, options: Required<PluginAngularLynxOptions>) => void;
5
+ /**
6
+ * This is copied from https://github.com/web-infra-dev/rsbuild/blob/037da7b9d92e20c7136c8b2efa21eef539fa2f88/packages/core/src/plugins/html.ts#L168
7
+ */
8
+ export declare const getChunks: (entryName: string, entryValue: (string | string[] | UndefinedOnPartialDeep<Rspack.EntryDescription>)[]) => {
9
+ chunks: string[];
10
+ imports: string[];
11
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { RsbuildPluginAPI } from '@lynx-js/rspeedy';
2
+ export declare const applyGenerator: (api: RsbuildPluginAPI) => void;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export { pluginAngularLynx } from './plugin-angular-lynx';