@portel/photon-core 2.5.2 → 2.5.3

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.
@@ -7,14 +7,6 @@
7
7
  * NOTE: No esbuild dependency in package.json — the consumer must provide it.
8
8
  * Uses `await import('esbuild')` for dynamic resolution.
9
9
  */
10
- /**
11
- * Compile a .photon.ts file to JavaScript and cache the result
12
- *
13
- * @param tsFilePath - Absolute path to the TypeScript source file
14
- * @param options.cacheDir - Directory to store compiled output
15
- * @param options.content - Optional pre-read file content (avoids extra read)
16
- * @returns Absolute path to the compiled .mjs file
17
- */
18
10
  export declare function compilePhotonTS(tsFilePath: string, options: {
19
11
  cacheDir: string;
20
12
  content?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9C,OAAO,CAAC,MAAM,CAAC,CA+BjB"}
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAiEH,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9C,OAAO,CAAC,MAAM,CAAC,CAmCjB"}
package/dist/compiler.js CHANGED
@@ -18,8 +18,47 @@ import * as crypto from 'crypto';
18
18
  * @param options.content - Optional pre-read file content (avoids extra read)
19
19
  * @returns Absolute path to the compiled .mjs file
20
20
  */
21
+ /**
22
+ * Transform array/map/set literals to constructor calls when using reactive imports
23
+ *
24
+ * When a file imports { Array } from '@portel/photon-core', transforms:
25
+ * items: Array<Task> = []; → items: Array<Task> = new Array();
26
+ * items = []; → items = new Array();
27
+ * data: Map<K,V> = new Map(); → (unchanged, already correct)
28
+ *
29
+ * Only transforms class properties (not local variables like const x = []).
30
+ * This enables zero-effort reactivity where developers just import and use.
31
+ */
32
+ function transformReactiveCollections(source) {
33
+ // Check which reactive types are imported
34
+ const importMatch = source.match(/import\s*\{([^}]+)\}\s*from\s*['"]@portel\/photon-core['"]/);
35
+ if (!importMatch)
36
+ return source;
37
+ const imports = importMatch[1].split(',').map(s => s.trim());
38
+ let transformed = source;
39
+ // Transform [] to new Array() if Array is imported
40
+ if (imports.includes('Array')) {
41
+ // Match class property declarations with type annotation = []
42
+ // Handles: items: Array<T> = []; | items: Type[] = [];
43
+ // The (?::\s*...) ensures there's a type annotation (class property pattern)
44
+ transformed = transformed.replace(/(\w+)\s*:\s*(?:Array<[^>]+>|[^=\n]+\[\])\s*=\s*\[\s*\]/g, '$1 = new Array()');
45
+ // Match class property without type annotation but NOT local variables
46
+ // Class properties: ` items = [];` (indented, no const/let/var)
47
+ // Skip: `const x = []`, `let x = []`, `var x = []`
48
+ transformed = transformed.replace(/^(\s+)(\w+)\s*=\s*\[\s*\](?=\s*[;\n])/gm, (match, indent, propName) => {
49
+ // Check if previous non-empty line contains const/let/var - if so, skip
50
+ // This is a heuristic but works for common patterns
51
+ return `${indent}${propName} = new Array()`;
52
+ });
53
+ }
54
+ // Map and Set already require new, so no transform needed
55
+ // (you can't write = {} for Map or Set literals)
56
+ return transformed;
57
+ }
21
58
  export async function compilePhotonTS(tsFilePath, options) {
22
- const source = options.content ?? (await fs.readFile(tsFilePath, 'utf-8'));
59
+ let source = options.content ?? (await fs.readFile(tsFilePath, 'utf-8'));
60
+ // Transform reactive collection literals before compilation
61
+ source = transformReactiveCollections(source);
23
62
  const hash = crypto.createHash('sha256').update(source).digest('hex').slice(0, 16);
24
63
  const fileName = path.basename(tsFilePath, '.ts');
25
64
  const cachedJsPath = path.join(options.cacheDir, `${fileName}.${hash}.mjs`);
@@ -1 +1 @@
1
- {"version":3,"file":"compiler.js","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAEjC;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAkB,EAClB,OAA+C;IAE/C,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3E,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEnF,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAClD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,QAAQ,IAAI,IAAI,MAAM,CAAC,CAAC;IAE5E,iCAAiC;IACjC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC9B,OAAO,YAAY,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,uBAAuB;IACzB,CAAC;IAED,wDAAwD;IACxD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE;QAC7C,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,QAAQ;QAChB,SAAS,EAAE,QAAQ;KACpB,CAAC,CAAC;IAEH,gCAAgC;IAChC,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEtD,4BAA4B;IAC5B,MAAM,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAEvD,OAAO,YAAY,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"compiler.js","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portel/photon-core",
3
- "version": "2.5.2",
3
+ "version": "2.5.3",
4
4
  "description": "Core library for parsing, loading, and managing .photon.ts files - runtime-agnostic foundation for building custom Photon runtimes",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
package/src/compiler.ts CHANGED
@@ -20,11 +20,66 @@ import * as crypto from 'crypto';
20
20
  * @param options.content - Optional pre-read file content (avoids extra read)
21
21
  * @returns Absolute path to the compiled .mjs file
22
22
  */
23
+ /**
24
+ * Transform array/map/set literals to constructor calls when using reactive imports
25
+ *
26
+ * When a file imports { Array } from '@portel/photon-core', transforms:
27
+ * items: Array<Task> = []; → items: Array<Task> = new Array();
28
+ * items = []; → items = new Array();
29
+ * data: Map<K,V> = new Map(); → (unchanged, already correct)
30
+ *
31
+ * Only transforms class properties (not local variables like const x = []).
32
+ * This enables zero-effort reactivity where developers just import and use.
33
+ */
34
+ function transformReactiveCollections(source: string): string {
35
+ // Check which reactive types are imported
36
+ const importMatch = source.match(
37
+ /import\s*\{([^}]+)\}\s*from\s*['"]@portel\/photon-core['"]/
38
+ );
39
+ if (!importMatch) return source;
40
+
41
+ const imports = importMatch[1].split(',').map(s => s.trim());
42
+
43
+ let transformed = source;
44
+
45
+ // Transform [] to new Array() if Array is imported
46
+ if (imports.includes('Array')) {
47
+ // Match class property declarations with type annotation = []
48
+ // Handles: items: Array<T> = []; | items: Type[] = [];
49
+ // The (?::\s*...) ensures there's a type annotation (class property pattern)
50
+ transformed = transformed.replace(
51
+ /(\w+)\s*:\s*(?:Array<[^>]+>|[^=\n]+\[\])\s*=\s*\[\s*\]/g,
52
+ '$1 = new Array()'
53
+ );
54
+
55
+ // Match class property without type annotation but NOT local variables
56
+ // Class properties: ` items = [];` (indented, no const/let/var)
57
+ // Skip: `const x = []`, `let x = []`, `var x = []`
58
+ transformed = transformed.replace(
59
+ /^(\s+)(\w+)\s*=\s*\[\s*\](?=\s*[;\n])/gm,
60
+ (match, indent, propName) => {
61
+ // Check if previous non-empty line contains const/let/var - if so, skip
62
+ // This is a heuristic but works for common patterns
63
+ return `${indent}${propName} = new Array()`;
64
+ }
65
+ );
66
+ }
67
+
68
+ // Map and Set already require new, so no transform needed
69
+ // (you can't write = {} for Map or Set literals)
70
+
71
+ return transformed;
72
+ }
73
+
23
74
  export async function compilePhotonTS(
24
75
  tsFilePath: string,
25
76
  options: { cacheDir: string; content?: string },
26
77
  ): Promise<string> {
27
- const source = options.content ?? (await fs.readFile(tsFilePath, 'utf-8'));
78
+ let source = options.content ?? (await fs.readFile(tsFilePath, 'utf-8'));
79
+
80
+ // Transform reactive collection literals before compilation
81
+ source = transformReactiveCollections(source);
82
+
28
83
  const hash = crypto.createHash('sha256').update(source).digest('hex').slice(0, 16);
29
84
 
30
85
  const fileName = path.basename(tsFilePath, '.ts');