@vamidicreations/arc-ui 0.1.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.
@@ -0,0 +1,292 @@
1
+ /**
2
+ * Tiny template compiler (rewritten for View.buildNodeTree)
3
+ *
4
+ * Instead of generating a standalone render function,
5
+ * we now generate code that overrides `Component.prototype.view.buildNodeTree`.
6
+ */
7
+ import * as parse5 from "parse5";
8
+ // small HTML tag whitelist (add more as needed)
9
+ const HTML_TAGS = new Set([
10
+ "a", "abbr", "address", "area", "article", "aside", "audio",
11
+ "b", "base", "bdi", "bdo", "blockquote", "body", "br", "button",
12
+ "canvas", "caption", "cite", "code", "col", "colgroup",
13
+ "data", "datalist", "dd", "del", "details", "dfn", "dialog", "div", "dl", "dt",
14
+ "em", "embed",
15
+ "fieldset", "figcaption", "figure", "footer", "form",
16
+ "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hr", "html",
17
+ "i", "iframe", "img", "input", "ins",
18
+ "kbd", "label", "legend", "li", "link",
19
+ "main", "map", "mark", "meta", "meter",
20
+ "nav", "noscript",
21
+ "object", "ol", "optgroup", "option", "output",
22
+ "p", "picture", "pre", "progress",
23
+ "q",
24
+ "rp", "rt", "ruby",
25
+ "s", "samp", "script", "section", "select", "small", "source", "span", "strong", "style", "sub", "summary", "sup",
26
+ "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track",
27
+ "u", "ul",
28
+ "var", "video", "wbr"
29
+ ]);
30
+ class TemplateComponentCompiler {
31
+ idCounter = 0;
32
+ generated = [];
33
+ rootVar = "root";
34
+ ctxVar = "ctx";
35
+ compileHtmlToRender(html, /* compName: string, */ selector) {
36
+ this.resetCounter();
37
+ this.resetGeneratedHtml();
38
+ const fragment = this.parseHtml(html);
39
+ // Build the node tree from the app to all the elements and components
40
+ this.generateNodeTree(fragment, selector);
41
+ return this.generated.join("\n");
42
+ }
43
+ id(name) {
44
+ return `${name}_${++this.idCounter}`;
45
+ }
46
+ isNativeHtmlTag(tagName) {
47
+ // custom elements per spec must contain a hyphen => treat as custom
48
+ const tag = String(tagName).toLowerCase();
49
+ if (tag.includes('-')) {
50
+ return false;
51
+ }
52
+ // otherwise, if it's a known HTML tag, it's native
53
+ return HTML_TAGS.has(tag);
54
+ }
55
+ resetCounter() {
56
+ this.idCounter = 0;
57
+ }
58
+ resetGeneratedHtml() {
59
+ this.generated = [];
60
+ }
61
+ parseHtml(html) {
62
+ return parse5.parseFragment(html);
63
+ }
64
+ generateNodeTree(fragment, selector) {
65
+ // buildNodeTree override
66
+ // Instead of attaching to prototype, register in central registry
67
+ this.generated.push(`registry.registerBuildTree("${selector}", function() {`);
68
+ this.generated.push(` const ${this.rootVar} = [];`);
69
+ this.generated.push(` const ${this.ctxVar} = this;`);
70
+ this.generateChildNodes(fragment);
71
+ this.generated.push(` return ${this.rootVar};`);
72
+ this.generated.push(`});`);
73
+ }
74
+ generateChildNodes(fragment) {
75
+ for (const node of fragment.childNodes) {
76
+ this.walkNodes([node], null, " ");
77
+ }
78
+ }
79
+ walkNodes(nodes, parentVar, indent = " ") {
80
+ for (const node of nodes) {
81
+ if (node.nodeName === "#text") {
82
+ const raw = node.value;
83
+ if (!raw || !raw.trim())
84
+ continue;
85
+ this.processTextNode(raw, parentVar, indent);
86
+ continue;
87
+ }
88
+ this.walkElement(node, parentVar, indent);
89
+ }
90
+ }
91
+ walkElement(node, parentVar, indent = " ") {
92
+ const tagName = node.tagName;
93
+ const customComponent = this.detectCustomComponentAndGenerate(tagName, parentVar, indent);
94
+ if (customComponent) {
95
+ return;
96
+ }
97
+ const routerComponent = this.detectRouterOutletComponent(tagName, parentVar, indent);
98
+ if (routerComponent) {
99
+ return;
100
+ }
101
+ const element = this.createElement(node, indent);
102
+ this.createStylesForElement(node, element, indent);
103
+ this.generateFunctions(node, element, indent);
104
+ this.addToParentOrRoot(element, parentVar, indent);
105
+ if (node.childNodes && node.childNodes.length) {
106
+ this.walkNodes(node.childNodes, element, indent + " ");
107
+ }
108
+ }
109
+ createElement(node, indent) {
110
+ const element = this.id("el");
111
+ this.generated.push(`${indent}const ${element} = onejsDocument.createElement(${JSON.stringify(node.tagName)});`);
112
+ (node.attrs || []).forEach((attr) => {
113
+ if (attr.name.startsWith("("))
114
+ return;
115
+ if (attr.name === "style")
116
+ return;
117
+ // support element refs
118
+ if (attr.name.startsWith('#')) {
119
+ const refName = attr.name.slice(1);
120
+ this.generated.push(`viewRegistry.add('${refName}', ${element});`);
121
+ }
122
+ this.generated.push(`${indent}${element}.setAttribute(${JSON.stringify(attr.name)}, ${JSON.stringify(attr.value)});`);
123
+ });
124
+ return element;
125
+ }
126
+ createStylesForElement(node, element, indent) {
127
+ const styleAttr = this.getAttr(node, "style");
128
+ if (styleAttr) {
129
+ const stylePairs = this.parseStyleString(styleAttr);
130
+ stylePairs.forEach((pair) => {
131
+ this.generated.push(`${indent}${element}.style.setProperty(${JSON.stringify(pair.prop)}, ${JSON.stringify(pair.val)});`);
132
+ });
133
+ }
134
+ }
135
+ createTextNode(id, text, indent) {
136
+ const textVar = this.id(id);
137
+ this.generated.push(`${indent}const ${textVar} = onejsDocument.createTextNode(${text});`);
138
+ return textVar;
139
+ }
140
+ generateFunctions(node, element, indent) {
141
+ (node.attrs || []).forEach((attr) => {
142
+ if (!attr.name.startsWith("("))
143
+ return;
144
+ const ev = attr.name.slice(1, -1);
145
+ const handlerCode = attr.value.trim();
146
+ const generateButtonEvt = `
147
+ ${indent}${element}.addEventListener(${JSON.stringify(ev)}, function(ev){ ${this.ctxVar}.${handlerCode} });
148
+ `;
149
+ this.generated.push(generateButtonEvt);
150
+ });
151
+ }
152
+ addToParentOrRoot(element, parentVar, indent) {
153
+ if (parentVar) {
154
+ this.generated.push(`${indent}${parentVar}.appendChild(${element});`);
155
+ }
156
+ else {
157
+ this.generated.push(` ${this.rootVar}.push(${element});`);
158
+ }
159
+ }
160
+ /**
161
+ * 🔹 Detect custom component tags (PascalCase convention, or however you decide)
162
+ * @param tagName
163
+ * @param parentVar
164
+ * @param indent
165
+ * @private
166
+ */
167
+ detectCustomComponentAndGenerate(tagName, parentVar, indent) {
168
+ if (this.isNativeHtmlTag(tagName)) {
169
+ return false;
170
+ }
171
+ const compTypeVar = this.id("compType");
172
+ const compVar = this.id("comp");
173
+ const treeVar = this.id("tree");
174
+ const componentGeneration = `
175
+ ${indent}// component <${tagName}>
176
+ ${indent}const ${compTypeVar} = registry.getComponentFromRegistry("${tagName}");
177
+
178
+ if(!${compTypeVar}) {
179
+ throw new Error(\`${tagName} can't be found!\`)
180
+ }
181
+
182
+ ${indent}const ${compVar} = new ${compTypeVar}();
183
+ ${indent}const ${treeVar} = ${compVar}.buildNodeTree();
184
+ `;
185
+ this.generated.push(componentGeneration);
186
+ // Add the children to the component
187
+ this.generated.push(`${indent}${treeVar}.forEach(n => {`);
188
+ this.addToParentOrRoot('n', parentVar, indent);
189
+ this.generated.push(`${indent}});`);
190
+ return true;
191
+ }
192
+ detectRouterOutletComponent(tagName, parentVar, indent) {
193
+ if (tagName !== "router-outlet") {
194
+ return false;
195
+ }
196
+ const outletVar = this.id("outlet");
197
+ this.generated.push(`
198
+ const ${outletVar} = onejsDocument.createElement("div");
199
+ root.push(${outletVar});
200
+
201
+ privateEffect(async () => {
202
+ const compType = await router.getComponent();
203
+ if (compType) {
204
+ const comp = new compType();
205
+ const tree = comp.buildNodeTree();
206
+ ${outletVar}.innerHTML = ""; // clear old view
207
+ tree.forEach(n => ${outletVar}.appendChild(n));
208
+ }
209
+ }, [router.currentPath]);
210
+ `);
211
+ this.addToParentOrRoot(outletVar, parentVar, indent);
212
+ return true;
213
+ }
214
+ processTextNode(rawValue, parentVar, indent) {
215
+ // Detect {{ expr }}
216
+ const regex = /\{\{([^}]+)}}/g;
217
+ let match;
218
+ let lastIndex = 0;
219
+ let hasInterpolation = false;
220
+ while ((match = regex.exec(rawValue))) {
221
+ hasInterpolation = true;
222
+ const staticText = rawValue.slice(lastIndex, match.index);
223
+ // we first have to check if the value is a signal, because
224
+ // then we need to attach them together immediately instead of making to text nodes.
225
+ if (match[1]) {
226
+ const expr = match[1].trim();
227
+ const dynTextVar = this.createTextNode("dynText", "\"\"", indent);
228
+ this.addToParentOrRoot(dynTextVar, parentVar, indent);
229
+ const isFunctionExpr = /\(\s*\)$/.test(expr); // true if expr ends with ()
230
+ const cleanExpr = expr.replace(/\(\s*\)$/, ""); // remove () for deps if present
231
+ if (isFunctionExpr) {
232
+ this.generated.push(`
233
+ ${indent}// listen to signal change
234
+ ${indent}privateEffect(() => {
235
+ ${indent}try {
236
+ ${indent}${dynTextVar}.nodeValue = String(${JSON.stringify(staticText)} + ${this.ctxVar}.${expr});
237
+ ${indent}} catch (e) {
238
+ ${indent}console.error(e);
239
+ ${indent}}
240
+ ${indent}}, [${this.ctxVar}.${cleanExpr}]);
241
+ `);
242
+ }
243
+ else {
244
+ this.generated.push(`
245
+ ${indent}try {
246
+ ${indent}${dynTextVar}.nodeValue = String(${JSON.stringify(staticText)} + ${this.ctxVar}.${expr});
247
+ ${indent}} catch (e) {
248
+ ${indent}console.error(e);
249
+ ${indent}}
250
+ `);
251
+ }
252
+ }
253
+ else {
254
+ if (staticText.trim()) {
255
+ console.log('parentVar', parentVar);
256
+ console.log('staticText', staticText);
257
+ const textVar = this.createTextNode("text", JSON.stringify(staticText), indent);
258
+ this.addToParentOrRoot(textVar, parentVar, indent);
259
+ }
260
+ }
261
+ lastIndex = regex.lastIndex;
262
+ }
263
+ if (!hasInterpolation) {
264
+ // plain text
265
+ const textVar = this.createTextNode("text", JSON.stringify(rawValue), indent);
266
+ this.addToParentOrRoot(textVar, parentVar, indent);
267
+ }
268
+ else if (lastIndex < rawValue.length) {
269
+ // leftover static text
270
+ const leftover = rawValue.slice(lastIndex);
271
+ const textVar = this.createTextNode("text", JSON.stringify(leftover), indent);
272
+ this.addToParentOrRoot(textVar, parentVar, indent);
273
+ }
274
+ }
275
+ parseStyleString(style) {
276
+ const out = [];
277
+ style.split(";").forEach((pair) => {
278
+ const [k, v] = pair.split(":");
279
+ if (!k || !v)
280
+ return;
281
+ out.push({ prop: k.trim(), val: v.trim() });
282
+ });
283
+ return out;
284
+ }
285
+ getAttr(node, name) {
286
+ if (!node.attrs)
287
+ return null;
288
+ const a = node.attrs.find((x) => x.name === name);
289
+ return a ? a.value : null;
290
+ }
291
+ }
292
+ export const templateComponentCompiler = new TemplateComponentCompiler();
@@ -0,0 +1,45 @@
1
+ /* component-plugin.ts
2
+ * tiny-compiler.js should export a function that takes (html, compName) and returns JS code
3
+ */
4
+ import { promises as fs } from 'fs';
5
+ import { resolve, dirname } from 'path';
6
+ import { templateComponentCompiler } from "./compiler/template-component.compiler";
7
+ const TS_EXT_PATTERN = /\.(ts|mts|cts|tsx)/;
8
+ export function componentPlugin() {
9
+ return {
10
+ name: "component-plugin",
11
+ setup(build) {
12
+ build.onLoad({ filter: TS_EXT_PATTERN }, async (args) => {
13
+ console.log("PLUGIN onLoad:", args.path);
14
+ let source = await fs.readFile(args.path, { encoding: "utf8" });
15
+ // Look for @Component with templateUrl
16
+ const match = source.match(/@Component\s*\(\s*{[^}]*templateUrl\s*:\s*['"](.+?)['"]/);
17
+ if (!match) {
18
+ return { contents: source, loader: "ts" };
19
+ }
20
+ if (!match[1]) {
21
+ return { contents: source, loader: "ts" };
22
+ }
23
+ const htmlPath = resolve(dirname(args.path), match[1]);
24
+ const html = await fs.readFile(htmlPath, "utf8");
25
+ const compNameMatch = source.match(/export\s+class\s+(\w+)/);
26
+ const compName = compNameMatch ? compNameMatch[1] : null; // "AnonymousComponent";
27
+ const selectorMatch = source.match(/selector\s*:\s*["'`](.*?)["'`]/);
28
+ const selector = selectorMatch ? selectorMatch[1] : null;
29
+ if (!compName || !selector) {
30
+ return { contents: source, loader: "ts" };
31
+ }
32
+ // Compile HTML → render fn
33
+ const renderFnCode = templateComponentCompiler.compileHtmlToRender(html, selector);
34
+ // Inject
35
+ const newSource = source +
36
+ "\n\n// --- generated render fn ---\n" +
37
+ renderFnCode;
38
+ return {
39
+ contents: newSource,
40
+ loader: "ts", // 👈 important: hand it back as TypeScript
41
+ };
42
+ });
43
+ }
44
+ };
45
+ }
@@ -0,0 +1,48 @@
1
+ import { promises as fs } from 'fs';
2
+ const privateEffectText = `
3
+ "use strict";
4
+ function privateEffect(effectFn, deps) {
5
+ let node = createViewEffect(effectFn, deps);
6
+ const effectRef = new EffectRefImpl(node);
7
+ effectFn();
8
+ return effectRef;
9
+ }
10
+ `;
11
+ const effectText = `
12
+ "use strict";
13
+ ${privateEffectText}
14
+ function createViewEffect(effectFn, deps) {
15
+ const node = alienEffect(effectFn);
16
+
17
+ const effectNode = node as unknown as EffectNode;
18
+ effectNode.fn = effectFn;
19
+ if (/* ngDevMode */ true) {
20
+ effectNode.toString = () => \`[Effect: router}]\`;
21
+ // @ts-ignore
22
+ effectNode.debugName = options?.debugName;
23
+ }
24
+
25
+ return effectNode;
26
+ }
27
+ `;
28
+ export function injectEffectPlugin() {
29
+ return {
30
+ name: "inject-effect",
31
+ setup(build) {
32
+ build.onEnd(async (result) => {
33
+ for (const out of result.outputFiles || []) {
34
+ let text = out.text;
35
+ if (!text.includes("function effect(")) {
36
+ text = effectText + '\n' + text;
37
+ console.log(`[effectPlugin] Injected effect() into ${out.path}`);
38
+ }
39
+ else {
40
+ text = privateEffectText + '\n' + text;
41
+ }
42
+ // ✅ Always write, even if unmodified (prevents missing file issue)
43
+ await fs.writeFile(out.path, text);
44
+ }
45
+ });
46
+ }
47
+ };
48
+ }
@@ -0,0 +1,3 @@
1
+ export * from './onejs';
2
+ export * from './component-plugin';
3
+ export * from './include-effect-plugin';
@@ -0,0 +1,79 @@
1
+ import { cpSync, existsSync, readdirSync, readFileSync, statSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { createHash } from 'crypto';
4
+ function getPackagesWithAssets() {
5
+ let packagesWithAssets = [];
6
+ const nodeModulesPath = join(process.cwd(), 'node_modules');
7
+ const packages = readdirSync(nodeModulesPath);
8
+ // console.log("There are " + packages.length + " packages in node_modules");
9
+ for (const packageName of packages) {
10
+ const packagePath = join(nodeModulesPath, packageName);
11
+ if (!statSync(packagePath).isDirectory())
12
+ continue;
13
+ const pkgJsonPath = join(packagePath, 'package.json');
14
+ try {
15
+ const pkgJsonContent = readFileSync(pkgJsonPath, 'utf8');
16
+ const pkgJson = JSON.parse(pkgJsonContent);
17
+ if (pkgJson.onejs && pkgJson.onejs['assets-path']) {
18
+ packagesWithAssets.push({
19
+ name: packageName,
20
+ src: join("node_modules", packageName, pkgJson.onejs['assets-path'])
21
+ });
22
+ }
23
+ }
24
+ catch (error) {
25
+ if (error.code !== 'ENOENT') {
26
+ console.error(`Error processing ${packageName}:`, error);
27
+ }
28
+ }
29
+ }
30
+ // console.log("Found " + packagesWithAssets.length + " packages with assets");
31
+ return packagesWithAssets;
32
+ }
33
+ const getDigest = (string) => {
34
+ const hash = createHash('md5');
35
+ const data = hash.update(string, 'utf-8');
36
+ return data.digest('hex');
37
+ };
38
+ const getFileDigest = (path) => {
39
+ if (!existsSync(path)) {
40
+ return null;
41
+ }
42
+ if (statSync(path).isDirectory()) {
43
+ return null;
44
+ }
45
+ return getDigest(readFileSync(path));
46
+ };
47
+ function filter(src, dest) {
48
+ if (!existsSync(dest)) {
49
+ return true;
50
+ }
51
+ if (statSync(dest).isDirectory()) {
52
+ return true;
53
+ }
54
+ return getFileDigest(src) !== getFileDigest(dest);
55
+ }
56
+ export function copyAssetsPlugin(options = {}) {
57
+ let dest = options.dest || 'assets';
58
+ return {
59
+ name: "onejs-copy-assets",
60
+ setup(build) {
61
+ build.onEnd(async () => {
62
+ const packagesWithAssets = getPackagesWithAssets();
63
+ console.log(`[esbuild] syncing assets from:`);
64
+ for (const pkg of packagesWithAssets) {
65
+ const destPath = join(dest, "@" + pkg.name);
66
+ cpSync(pkg.src, destPath, {
67
+ dereference: options.dereference || true,
68
+ errorOnExist: options.errorOnExist || false,
69
+ filter: options.filter || filter,
70
+ force: options.force || true,
71
+ preserveTimestamps: options.preserveTimestamps || true,
72
+ recursive: options.recursive || true,
73
+ });
74
+ console.log(`[esbuild] > ${pkg.name}`);
75
+ }
76
+ });
77
+ }
78
+ };
79
+ }
@@ -0,0 +1,14 @@
1
+ import { readFileSync, writeFileSync } from 'fs';
2
+ export function decoratorFixPlugin(options = {}) {
3
+ const outfile = options.outfile || "@outputs/esbuild/app.js";
4
+ return {
5
+ name: "decorator-fix-plugin",
6
+ setup(build) {
7
+ build.onEnd(() => {
8
+ let content = readFileSync(outfile, "utf8");
9
+ content = content.replace(/exports\s*&&\s*exports\.__decorate/g, 'typeof exports !== "undefined" && exports.__decorate');
10
+ writeFileSync(outfile, content, "utf8");
11
+ });
12
+ }
13
+ };
14
+ }
@@ -0,0 +1,86 @@
1
+ import { promises as fs } from 'fs';
2
+ import { extname } from 'path';
3
+ /**
4
+ * Copied from OneJs
5
+ * An esbuild plugin that transforms imports from modules starting with a capital letter.
6
+ *
7
+ * ## Functionality:
8
+ * 1. **Externalizing Capitalized Module Imports**:
9
+ * - Marks imports from modules with names starting with a capital letter as external
10
+ * during the resolution phase.
11
+ *
12
+ * 2. **Transforming Import Statements**:
13
+ * - Rewrites ES module import statements to reference a global `CS` object.
14
+ * - Converts:
15
+ * ```js
16
+ * import { Foo, Bar } from "MyModule";
17
+ * ```
18
+ * Into:
19
+ * ```js
20
+ * const { Foo, Bar } = CS.MyModule;
21
+ * ```
22
+ * - If the import is a default import or namespace import:
23
+ * ```js
24
+ * import MyModule from "MyModule";
25
+ * ```
26
+ * Becomes:
27
+ * ```js
28
+ * const MyModule = CS.MyModule;
29
+ * ```
30
+ *
31
+ * 3. **Handling `require` Statements**:
32
+ * - Transforms `__require("MyModule")` into `CS.MyModule`.
33
+ *
34
+ * ## Parameters:
35
+ * @param {Object} options - Configuration options.
36
+ * @param {Function} [options.moduleFilter] - A filter function that determines if a module should be transformed.
37
+ *
38
+ * ## Returns:
39
+ * @returns {Object} An esbuild plugin object.
40
+ *
41
+ * ## Example Usage:
42
+ *
43
+ * ```js
44
+ * importTransformation({
45
+ * moduleFilter: (moduleName) => moduleName.startsWith("MyLib")
46
+ * });
47
+ * ```
48
+ *
49
+ */
50
+ export function importTransformationPlugin(options = {}) {
51
+ const moduleFilter = options.moduleFilter || (() => true);
52
+ return {
53
+ name: "onejs-import-transform",
54
+ setup(build) {
55
+ // First pass: Mark imports from modules starting with a capital letter as external
56
+ build.onResolve({ filter: /^[A-Z]/ }, (args) => {
57
+ return { path: args.path, external: true };
58
+ });
59
+ // Second pass: Transform all JS and TSX files
60
+ build.onLoad({ filter: /\.(js|jsx|ts|tsx)$/ }, async (args) => {
61
+ let contents = await fs.readFile(args.path, "utf8");
62
+ // Transform imports from modules starting with a capital letter
63
+ contents = contents.replace(/import\s+(?:{([^}]+)})?\s*from\s*["']([A-Z][^"']*)["'];?/g, (match, imports, moduleName) => {
64
+ if (!moduleFilter(moduleName))
65
+ return match;
66
+ moduleName = moduleName.replace(/\//g, ".");
67
+ if (imports) {
68
+ const importItems = imports.split(",").map((item) => item.trim());
69
+ return `const { ${importItems.join(", ")} } = CS.${moduleName};`;
70
+ }
71
+ else {
72
+ const namespaceName = moduleName.split(".").pop();
73
+ return `const ${namespaceName} = CS.${moduleName};`;
74
+ }
75
+ });
76
+ // Transform any remaining require statements for such modules
77
+ contents = contents.replace(/__require\(["']([A-Z][^"']*)["']\)/g, (match, moduleName) => {
78
+ if (!moduleFilter(moduleName))
79
+ return match;
80
+ return `CS.${moduleName.replace(/\//g, ".")}`;
81
+ });
82
+ return { contents, loader: extname(args.path).slice(1) };
83
+ });
84
+ },
85
+ };
86
+ }
@@ -0,0 +1,3 @@
1
+ export * from './import-transform';
2
+ export * from './copy-assets';
3
+ export * from './decorator-fix';
package/jest.config.js ADDED
@@ -0,0 +1,13 @@
1
+ /** @type {import('ts-jest').JestConfigWithTsJest} **/
2
+ module.exports = {
3
+ testEnvironment: "node",
4
+ transform: {
5
+ "^.+\\.(js|jsx|ts|tsx)$": "ts-jest",
6
+ },
7
+ transformIgnorePatterns: [
8
+ "node_modules/(?!@ngrx|(?!deck.gl)|ng-dynamic)"
9
+ ],
10
+ testPathIgnorePatterns: [
11
+ "<rootDir>/node_modules/",
12
+ ],
13
+ }
package/main.mjs ADDED
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Default OneJS ESbuild Config
3
+ */
4
+ import { context } from "esbuild";
5
+ import { componentPlugin, injectEffectPlugin, importTransformationPlugin, copyAssetsPlugin, decoratorFixPlugin } from "./src";
6
+ // @ts-ignore
7
+ const once = process.argv.includes("--once");
8
+ // !once && outputWatcherPlugin(),
9
+ const ctx = await context({
10
+ entryPoints: ["./src/main.ts"],
11
+ bundle: true,
12
+ plugins: [
13
+ componentPlugin(),
14
+ importTransformationPlugin(),
15
+ copyAssetsPlugin(),
16
+ decoratorFixPlugin(),
17
+ {
18
+ name: 'add-mjs',
19
+ setup(build) {
20
+ build.onResolve({ filter: /.*/ }, args => {
21
+ if (args.importer)
22
+ return { path: args.path + '.mjs', external: true };
23
+ });
24
+ }
25
+ },
26
+ injectEffectPlugin(),
27
+ ],
28
+ inject: ["onejs-core/dist/index.js"],
29
+ platform: "node",
30
+ sourcemap: true,
31
+ sourceRoot: process.cwd() + "/index",
32
+ alias: {
33
+ "onejs": "onejs-core",
34
+ "esbuild": "esbuild",
35
+ },
36
+ outfile: "@outputs/esbuild/app.js",
37
+ write: false, // override
38
+ });
39
+ if (once) {
40
+ await ctx.rebuild();
41
+ await ctx.dispose();
42
+ console.log("Build finished.");
43
+ process.exit(0);
44
+ }
45
+ else {
46
+ await ctx.watch();
47
+ console.log("Watching for changes…");
48
+ }