@esportsplus/reactivity 0.25.7 → 0.25.9

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.
@@ -1,9 +1,9 @@
1
- declare const COMPILATION_ENTRYPOINT = "reactive";
2
- declare const COMPILATION_ENTRYPOINT_REGEX: RegExp;
3
- declare const COMPILATION_NAMESPACE: string;
4
- declare const COMPILATION_TYPE_ARRAY = "array";
5
- declare const COMPILATION_TYPE_COMPUTED = "computed";
6
- declare const COMPILATION_TYPE_SIGNAL = "signal";
1
+ declare const COMPILER_ENTRYPOINT = "reactive";
2
+ declare const COMPILER_ENTRYPOINT_REGEX: RegExp;
3
+ declare const COMPILER_NAMESPACE: string;
4
+ declare const COMPILER_TYPE_ARRAY = "array";
5
+ declare const COMPILER_TYPE_COMPUTED = "computed";
6
+ declare const COMPILER_TYPE_SIGNAL = "signal";
7
7
  declare const COMPUTED: unique symbol;
8
8
  declare const PACKAGE = "@esportsplus/reactivity";
9
9
  declare const REACTIVE_ARRAY: unique symbol;
@@ -19,4 +19,4 @@ declare const STATE_DIRTY: number;
19
19
  declare const STATE_RECOMPUTING: number;
20
20
  declare const STATE_IN_HEAP: number;
21
21
  declare const STATE_NOTIFY_MASK: number;
22
- export { COMPILATION_TYPE_ARRAY, COMPILATION_TYPE_COMPUTED, COMPILATION_ENTRYPOINT, COMPILATION_ENTRYPOINT_REGEX, COMPILATION_NAMESPACE, COMPILATION_TYPE_SIGNAL, COMPUTED, PACKAGE, REACTIVE_ARRAY, REACTIVE_OBJECT, SIGNAL, STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_NOTIFY_MASK, STATE_RECOMPUTING };
22
+ export { COMPILER_TYPE_ARRAY, COMPILER_TYPE_COMPUTED, COMPILER_ENTRYPOINT, COMPILER_ENTRYPOINT_REGEX, COMPILER_NAMESPACE, COMPILER_TYPE_SIGNAL, COMPUTED, PACKAGE, REACTIVE_ARRAY, REACTIVE_OBJECT, SIGNAL, STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_NOTIFY_MASK, STATE_RECOMPUTING };
@@ -1,10 +1,10 @@
1
1
  import { uid } from '@esportsplus/typescript/transformer';
2
- const COMPILATION_ENTRYPOINT = 'reactive';
3
- const COMPILATION_ENTRYPOINT_REGEX = /\breactive\b/;
4
- const COMPILATION_NAMESPACE = uid(COMPILATION_ENTRYPOINT);
5
- const COMPILATION_TYPE_ARRAY = 'array';
6
- const COMPILATION_TYPE_COMPUTED = 'computed';
7
- const COMPILATION_TYPE_SIGNAL = 'signal';
2
+ const COMPILER_ENTRYPOINT = 'reactive';
3
+ const COMPILER_ENTRYPOINT_REGEX = /\breactive\b/;
4
+ const COMPILER_NAMESPACE = uid(COMPILER_ENTRYPOINT);
5
+ const COMPILER_TYPE_ARRAY = 'array';
6
+ const COMPILER_TYPE_COMPUTED = 'computed';
7
+ const COMPILER_TYPE_SIGNAL = 'signal';
8
8
  const COMPUTED = Symbol('reactivity.computed');
9
9
  const PACKAGE = '@esportsplus/reactivity';
10
10
  const REACTIVE_ARRAY = Symbol('reactivity.reactive.array');
@@ -20,4 +20,4 @@ const STATE_DIRTY = 1 << 1;
20
20
  const STATE_RECOMPUTING = 1 << 2;
21
21
  const STATE_IN_HEAP = 1 << 3;
22
22
  const STATE_NOTIFY_MASK = (STATE_CHECK | STATE_DIRTY);
23
- export { COMPILATION_TYPE_ARRAY, COMPILATION_TYPE_COMPUTED, COMPILATION_ENTRYPOINT, COMPILATION_ENTRYPOINT_REGEX, COMPILATION_NAMESPACE, COMPILATION_TYPE_SIGNAL, COMPUTED, PACKAGE, REACTIVE_ARRAY, REACTIVE_OBJECT, SIGNAL, STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_NOTIFY_MASK, STATE_RECOMPUTING };
23
+ export { COMPILER_TYPE_ARRAY, COMPILER_TYPE_COMPUTED, COMPILER_ENTRYPOINT, COMPILER_ENTRYPOINT_REGEX, COMPILER_NAMESPACE, COMPILER_TYPE_SIGNAL, COMPUTED, PACKAGE, REACTIVE_ARRAY, REACTIVE_OBJECT, SIGNAL, STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_NOTIFY_MASK, STATE_RECOMPUTING };
@@ -1,7 +1,7 @@
1
1
  import { ReactiveArray } from './array.js';
2
- import { COMPILATION_ENTRYPOINT, PACKAGE } from '../constants.js';
2
+ import { COMPILER_ENTRYPOINT, PACKAGE } from '../constants.js';
3
3
  function reactive(_input) {
4
- throw new Error(`${PACKAGE}: ${COMPILATION_ENTRYPOINT}() called at runtime. ` +
4
+ throw new Error(`${PACKAGE}: ${COMPILER_ENTRYPOINT}() called at runtime. ` +
5
5
  'Ensure vite plugin is configured.');
6
6
  }
7
7
  export default reactive;
@@ -1,5 +1,5 @@
1
1
  import { ts } from '@esportsplus/typescript';
2
2
  import type { TransformResult } from '../types.js';
3
- import { contains } from './detector.js';
3
+ declare function contains(code: string): boolean;
4
4
  declare const transform: (sourceFile: ts.SourceFile) => TransformResult;
5
5
  export { contains, transform };
@@ -1,17 +1,51 @@
1
1
  import { ts } from '@esportsplus/typescript';
2
- import { COMPILATION_NAMESPACE } from '../constants.js';
3
- import { contains } from './detector.js';
2
+ import { code as c } from '@esportsplus/typescript/transformer';
3
+ import { COMPILER_ENTRYPOINT, COMPILER_ENTRYPOINT_REGEX, COMPILER_NAMESPACE } from '../constants.js';
4
4
  import array from './transforms/array.js';
5
5
  import object from './transforms/object.js';
6
6
  import primitives from './transforms/primitives.js';
7
7
  let transforms = [object, array, primitives];
8
+ function contains(code) {
9
+ if (!c.contains(code, { regex: COMPILER_ENTRYPOINT_REGEX })) {
10
+ return false;
11
+ }
12
+ let ctx = {
13
+ imported: false,
14
+ used: false
15
+ };
16
+ visit(ctx, ts.createSourceFile('detect.ts', code, ts.ScriptTarget.Latest, false));
17
+ return ctx.imported && ctx.used;
18
+ }
19
+ function visit(ctx, node) {
20
+ if (ctx.imported && ctx.used) {
21
+ return;
22
+ }
23
+ if (ts.isImportDeclaration(node) &&
24
+ node.importClause?.namedBindings &&
25
+ ts.isNamedImports(node.importClause.namedBindings)) {
26
+ let elements = node.importClause.namedBindings.elements;
27
+ for (let i = 0, n = elements.length; i < n; i++) {
28
+ let element = elements[i];
29
+ if ((element.propertyName?.text ?? element.name.text) === COMPILER_ENTRYPOINT) {
30
+ ctx.imported = true;
31
+ break;
32
+ }
33
+ }
34
+ }
35
+ if (ts.isCallExpression(node) &&
36
+ ts.isIdentifier(node.expression) &&
37
+ node.expression.text === COMPILER_ENTRYPOINT) {
38
+ ctx.used = true;
39
+ }
40
+ ts.forEachChild(node, n => visit(ctx, n));
41
+ }
8
42
  const transform = (sourceFile) => {
9
43
  let bindings = new Map(), code = sourceFile.getFullText(), current = sourceFile, result, transformed = false;
10
44
  if (!contains(code)) {
11
45
  return { code, sourceFile, transformed: false };
12
46
  }
13
47
  for (let i = 0, n = transforms.length; i < n; i++) {
14
- result = transforms[i](current, bindings, COMPILATION_NAMESPACE);
48
+ result = transforms[i](current, bindings, COMPILER_NAMESPACE);
15
49
  if (result !== code) {
16
50
  current = ts.createSourceFile(sourceFile.fileName, result, sourceFile.languageVersion, true);
17
51
  code = result;
@@ -19,7 +53,7 @@ const transform = (sourceFile) => {
19
53
  }
20
54
  }
21
55
  if (transformed) {
22
- code = `import * as ${COMPILATION_NAMESPACE} from '@esportsplus/reactivity';\n` + code;
56
+ code = `import * as ${COMPILER_NAMESPACE} from '@esportsplus/reactivity';\n` + code;
23
57
  sourceFile = ts.createSourceFile(sourceFile.fileName, code, sourceFile.languageVersion, true);
24
58
  }
25
59
  return { code, sourceFile, transformed };
@@ -1,13 +1,13 @@
1
1
  import { ts } from '@esportsplus/typescript';
2
2
  import { TRANSFORM_PATTERN } from '@esportsplus/typescript/transformer';
3
- import { contains, transform } from '../../transformer/index.js';
3
+ import { transform } from '../../transformer/index.js';
4
4
  import { PACKAGE } from '../../constants.js';
5
5
  export default () => {
6
6
  return {
7
7
  enforce: 'pre',
8
8
  name: `${PACKAGE}/plugin-vite`,
9
9
  transform(code, id) {
10
- if (!TRANSFORM_PATTERN.test(id) || id.includes('node_modules') || !contains(code)) {
10
+ if (!TRANSFORM_PATTERN.test(id) || id.includes('node_modules')) {
11
11
  return null;
12
12
  }
13
13
  try {
@@ -1,6 +1,6 @@
1
1
  import { code as c } from '@esportsplus/typescript/transformer';
2
2
  import { ts } from '@esportsplus/typescript';
3
- import { COMPILATION_TYPE_ARRAY } from '../../constants.js';
3
+ import { COMPILER_TYPE_ARRAY } from '../../constants.js';
4
4
  function getExpressionName(node) {
5
5
  if (ts.isIdentifier(node)) {
6
6
  return node.text;
@@ -30,13 +30,13 @@ function isAssignmentTarget(node) {
30
30
  }
31
31
  function visit(ctx, node) {
32
32
  if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer) {
33
- if (ts.isIdentifier(node.initializer) && ctx.bindings.get(node.initializer.text) === COMPILATION_TYPE_ARRAY) {
34
- ctx.bindings.set(node.name.text, COMPILATION_TYPE_ARRAY);
33
+ if (ts.isIdentifier(node.initializer) && ctx.bindings.get(node.initializer.text) === COMPILER_TYPE_ARRAY) {
34
+ ctx.bindings.set(node.name.text, COMPILER_TYPE_ARRAY);
35
35
  }
36
36
  if (ts.isPropertyAccessExpression(node.initializer)) {
37
37
  let path = getPropertyPath(node.initializer);
38
- if (path && ctx.bindings.get(path) === COMPILATION_TYPE_ARRAY) {
39
- ctx.bindings.set(node.name.text, COMPILATION_TYPE_ARRAY);
38
+ if (path && ctx.bindings.get(path) === COMPILER_TYPE_ARRAY) {
39
+ ctx.bindings.set(node.name.text, COMPILER_TYPE_ARRAY);
40
40
  }
41
41
  }
42
42
  }
@@ -47,7 +47,7 @@ function visit(ctx, node) {
47
47
  ts.isTypeReferenceNode(param.type) &&
48
48
  ts.isIdentifier(param.type.typeName) &&
49
49
  param.type.typeName.text === 'ReactiveArray') {
50
- ctx.bindings.set(param.name.text, COMPILATION_TYPE_ARRAY);
50
+ ctx.bindings.set(param.name.text, COMPILER_TYPE_ARRAY);
51
51
  }
52
52
  }
53
53
  }
@@ -55,7 +55,7 @@ function visit(ctx, node) {
55
55
  node.name.text === 'length' &&
56
56
  !isAssignmentTarget(node)) {
57
57
  let name = getExpressionName(node.expression);
58
- if (name && ctx.bindings.get(name) === COMPILATION_TYPE_ARRAY) {
58
+ if (name && ctx.bindings.get(name) === COMPILER_TYPE_ARRAY) {
59
59
  let objText = node.expression.getText(ctx.sourceFile);
60
60
  ctx.replacements.push({
61
61
  end: node.end,
@@ -68,7 +68,7 @@ function visit(ctx, node) {
68
68
  node.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
69
69
  ts.isElementAccessExpression(node.left)) {
70
70
  let elemAccess = node.left, objName = getExpressionName(elemAccess.expression);
71
- if (objName && ctx.bindings.get(objName) === COMPILATION_TYPE_ARRAY) {
71
+ if (objName && ctx.bindings.get(objName) === COMPILER_TYPE_ARRAY) {
72
72
  let indexText = elemAccess.argumentExpression.getText(ctx.sourceFile), objText = elemAccess.expression.getText(ctx.sourceFile), valueText = node.right.getText(ctx.sourceFile);
73
73
  ctx.replacements.push({
74
74
  end: node.end,
@@ -1,6 +1,6 @@
1
1
  import { ts } from '@esportsplus/typescript';
2
2
  import { code as c } from '@esportsplus/typescript/transformer';
3
- import { COMPILATION_TYPE_ARRAY, COMPILATION_TYPE_COMPUTED, COMPILATION_TYPE_SIGNAL, PACKAGE } from '../../constants.js';
3
+ import { COMPILER_TYPE_ARRAY, COMPILER_TYPE_COMPUTED, COMPILER_TYPE_SIGNAL, PACKAGE } from '../../constants.js';
4
4
  function analyzeProperty(prop, sourceFile) {
5
5
  if (!ts.isPropertyAssignment(prop)) {
6
6
  return null;
@@ -14,7 +14,7 @@ function analyzeProperty(prop, sourceFile) {
14
14
  }
15
15
  let value = prop.initializer, valueText = value.getText(sourceFile);
16
16
  if (ts.isArrowFunction(value) || ts.isFunctionExpression(value)) {
17
- return { key, type: COMPILATION_TYPE_COMPUTED, valueText };
17
+ return { key, type: COMPILER_TYPE_COMPUTED, valueText };
18
18
  }
19
19
  if (ts.isArrayLiteralExpression(value)) {
20
20
  let elements = value.elements, elementsText = '';
@@ -24,26 +24,26 @@ function analyzeProperty(prop, sourceFile) {
24
24
  }
25
25
  elementsText += elements[i].getText(sourceFile);
26
26
  }
27
- return { key, type: COMPILATION_TYPE_ARRAY, valueText: elementsText };
27
+ return { key, type: COMPILER_TYPE_ARRAY, valueText: elementsText };
28
28
  }
29
- return { key, type: COMPILATION_TYPE_SIGNAL, valueText };
29
+ return { key, type: COMPILER_TYPE_SIGNAL, valueText };
30
30
  }
31
31
  function buildClassCode(className, properties, ns) {
32
32
  let accessors = [], disposeStatements = [], fields = [], paramCounter = 0;
33
33
  fields.push(`[${ns}.REACTIVE_OBJECT] = true;`);
34
34
  for (let i = 0, n = properties.length; i < n; i++) {
35
35
  let { key, type, valueText } = properties[i];
36
- if (type === COMPILATION_TYPE_SIGNAL) {
36
+ if (type === COMPILER_TYPE_SIGNAL) {
37
37
  let param = `_v${paramCounter++}`;
38
38
  fields.push(`#${key} = ${ns}.signal(${valueText});`);
39
39
  accessors.push(`get ${key}() { return ${ns}.read(this.#${key}); }`);
40
40
  accessors.push(`set ${key}(${param}) { ${ns}.write(this.#${key}, ${param}); }`);
41
41
  }
42
- else if (type === COMPILATION_TYPE_ARRAY) {
42
+ else if (type === COMPILER_TYPE_ARRAY) {
43
43
  fields.push(`${key} = new ${ns}.ReactiveArray(${valueText});`);
44
44
  disposeStatements.push(`this.${key}.dispose();`);
45
45
  }
46
- else if (type === COMPILATION_TYPE_COMPUTED) {
46
+ else if (type === COMPILER_TYPE_COMPUTED) {
47
47
  fields.push(`#${key} = null;`);
48
48
  accessors.push(`get ${key}() { return ${ns}.read(this.#${key} ??= ${ns}.computed(${valueText})); }`);
49
49
  disposeStatements.push(`if (this.#${key}) ${ns}.dispose(this.#${key});`);
@@ -100,8 +100,8 @@ function visit(ctx, node) {
100
100
  return;
101
101
  }
102
102
  properties.push(analyzed);
103
- if (analyzed.type === COMPILATION_TYPE_ARRAY && varName) {
104
- ctx.bindings.set(`${varName}.${analyzed.key}`, COMPILATION_TYPE_ARRAY);
103
+ if (analyzed.type === COMPILER_TYPE_ARRAY && varName) {
104
+ ctx.bindings.set(`${varName}.${analyzed.key}`, COMPILER_TYPE_ARRAY);
105
105
  }
106
106
  }
107
107
  ctx.calls.push({
@@ -1,6 +1,6 @@
1
1
  import { ts } from '@esportsplus/typescript';
2
2
  import { code as c } from '@esportsplus/typescript/transformer';
3
- import { COMPILATION_TYPE_COMPUTED, COMPILATION_ENTRYPOINT, COMPILATION_TYPE_SIGNAL, PACKAGE } from '../../constants.js';
3
+ import { COMPILER_TYPE_COMPUTED, COMPILER_ENTRYPOINT, COMPILER_TYPE_SIGNAL, PACKAGE } from '../../constants.js';
4
4
  let COMPOUND_OPERATORS = new Map([
5
5
  [ts.SyntaxKind.AmpersandAmpersandEqualsToken, '&&'],
6
6
  [ts.SyntaxKind.AmpersandEqualsToken, '&'],
@@ -20,12 +20,12 @@ let COMPOUND_OPERATORS = new Map([
20
20
  ]);
21
21
  function classifyReactiveArg(arg) {
22
22
  if (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg)) {
23
- return COMPILATION_TYPE_COMPUTED;
23
+ return COMPILER_TYPE_COMPUTED;
24
24
  }
25
25
  if (ts.isObjectLiteralExpression(arg) || ts.isArrayLiteralExpression(arg)) {
26
26
  return null;
27
27
  }
28
- return COMPILATION_TYPE_SIGNAL;
28
+ return COMPILER_TYPE_SIGNAL;
29
29
  }
30
30
  function findBinding(bindings, name, node) {
31
31
  for (let i = 0, n = bindings.length; i < n; i++) {
@@ -83,7 +83,7 @@ function isReactiveReassignment(node) {
83
83
  parent.right === node &&
84
84
  ts.isCallExpression(node) &&
85
85
  ts.isIdentifier(node.expression) &&
86
- node.expression.text === COMPILATION_ENTRYPOINT) {
86
+ node.expression.text === COMPILER_ENTRYPOINT) {
87
87
  return true;
88
88
  }
89
89
  return false;
@@ -114,7 +114,7 @@ function visit(ctx, node) {
114
114
  let clause = node.importClause;
115
115
  if (clause?.namedBindings && ts.isNamedImports(clause.namedBindings)) {
116
116
  for (let i = 0, n = clause.namedBindings.elements.length; i < n; i++) {
117
- if (clause.namedBindings.elements[i].name.text === COMPILATION_ENTRYPOINT) {
117
+ if (clause.namedBindings.elements[i].name.text === COMPILER_ENTRYPOINT) {
118
118
  ctx.hasReactiveImport = true;
119
119
  break;
120
120
  }
@@ -124,7 +124,7 @@ function visit(ctx, node) {
124
124
  if (ctx.hasReactiveImport &&
125
125
  ts.isCallExpression(node) &&
126
126
  ts.isIdentifier(node.expression) &&
127
- node.expression.text === COMPILATION_ENTRYPOINT &&
127
+ node.expression.text === COMPILER_ENTRYPOINT &&
128
128
  node.arguments.length > 0) {
129
129
  let arg = node.arguments[0], classification = classifyReactiveArg(arg);
130
130
  if (classification) {
@@ -143,7 +143,7 @@ function visit(ctx, node) {
143
143
  ctx.scopedBindings.push({ name: varName, scope, type: classification });
144
144
  ctx.bindings.set(varName, classification);
145
145
  }
146
- if (classification === COMPILATION_TYPE_COMPUTED) {
146
+ if (classification === COMPILER_TYPE_COMPUTED) {
147
147
  let argStart = arg.getStart(ctx.sourceFile);
148
148
  ctx.computedArgRanges.push({ end: arg.end, start: argStart });
149
149
  let argCtx = {
@@ -186,7 +186,7 @@ function visit(ctx, node) {
186
186
  !(ts.isTypeOfExpression(node.parent) && node.parent.expression === node)) {
187
187
  let writeCtx = isWriteContext(node);
188
188
  if (writeCtx) {
189
- if (binding.type !== COMPILATION_TYPE_COMPUTED) {
189
+ if (binding.type !== COMPILER_TYPE_COMPUTED) {
190
190
  let parent = node.parent;
191
191
  if (writeCtx === 'simple' && ts.isBinaryExpression(parent)) {
192
192
  ctx.replacements.push({
package/package.json CHANGED
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "type": "module",
38
38
  "types": "build/index.d.ts",
39
- "version": "0.25.7",
39
+ "version": "0.25.9",
40
40
  "scripts": {
41
41
  "build": "tsc",
42
42
  "build:test": "pnpm build && vite build --config test/vite.config.ts",
package/src/constants.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  import { uid } from '@esportsplus/typescript/transformer';
2
2
 
3
3
 
4
- const COMPILATION_ENTRYPOINT = 'reactive';
4
+ const COMPILER_ENTRYPOINT = 'reactive';
5
5
 
6
- const COMPILATION_ENTRYPOINT_REGEX = /\breactive\b/;
6
+ const COMPILER_ENTRYPOINT_REGEX = /\breactive\b/;
7
7
 
8
- const COMPILATION_NAMESPACE = uid(COMPILATION_ENTRYPOINT);
8
+ const COMPILER_NAMESPACE = uid(COMPILER_ENTRYPOINT);
9
9
 
10
- const COMPILATION_TYPE_ARRAY = 'array';
10
+ const COMPILER_TYPE_ARRAY = 'array';
11
11
 
12
- const COMPILATION_TYPE_COMPUTED = 'computed';
12
+ const COMPILER_TYPE_COMPUTED = 'computed';
13
13
 
14
- const COMPILATION_TYPE_SIGNAL = 'signal';
14
+ const COMPILER_TYPE_SIGNAL = 'signal';
15
15
 
16
16
 
17
17
  const COMPUTED = Symbol('reactivity.computed');
@@ -48,7 +48,7 @@ const STATE_NOTIFY_MASK = (STATE_CHECK | STATE_DIRTY);
48
48
 
49
49
 
50
50
  export {
51
- COMPILATION_TYPE_ARRAY, COMPILATION_TYPE_COMPUTED, COMPILATION_ENTRYPOINT, COMPILATION_ENTRYPOINT_REGEX, COMPILATION_NAMESPACE, COMPILATION_TYPE_SIGNAL, COMPUTED,
51
+ COMPILER_TYPE_ARRAY, COMPILER_TYPE_COMPUTED, COMPILER_ENTRYPOINT, COMPILER_ENTRYPOINT_REGEX, COMPILER_NAMESPACE, COMPILER_TYPE_SIGNAL, COMPUTED,
52
52
  PACKAGE,
53
53
  REACTIVE_ARRAY, REACTIVE_OBJECT,
54
54
  SIGNAL,
@@ -1,5 +1,5 @@
1
1
  import { ReactiveArray } from './array';
2
- import { COMPILATION_ENTRYPOINT, PACKAGE } from '~/constants';
2
+ import { COMPILER_ENTRYPOINT, PACKAGE } from '~/constants';
3
3
  import { Reactive } from '~/types';
4
4
 
5
5
 
@@ -14,7 +14,7 @@ type Guard<T> =
14
14
  function reactive<T extends Record<PropertyKey, any>>(_input: Guard<T>): Reactive<T>;
15
15
  function reactive<T>(_input: T): Reactive<T> {
16
16
  throw new Error(
17
- `${PACKAGE}: ${COMPILATION_ENTRYPOINT}() called at runtime. ` +
17
+ `${PACKAGE}: ${COMPILER_ENTRYPOINT}() called at runtime. ` +
18
18
  'Ensure vite plugin is configured.'
19
19
  );
20
20
  }
@@ -1,7 +1,7 @@
1
1
  import { ts } from '@esportsplus/typescript';
2
- import { COMPILATION_NAMESPACE } from '~/constants.js';
2
+ import { code as c } from '@esportsplus/typescript/transformer';
3
+ import { COMPILER_ENTRYPOINT, COMPILER_ENTRYPOINT_REGEX, COMPILER_NAMESPACE } from '~/constants';
3
4
  import type { Bindings, TransformResult } from '~/types';
4
- import { contains } from './detector';
5
5
  import array from './transforms/array';
6
6
  import object from './transforms/object';
7
7
  import primitives from './transforms/primitives';
@@ -10,6 +10,55 @@ import primitives from './transforms/primitives';
10
10
  let transforms = [object, array, primitives];
11
11
 
12
12
 
13
+ function contains(code: string): boolean {
14
+ if (!c.contains(code, { regex: COMPILER_ENTRYPOINT_REGEX })) {
15
+ return false;
16
+ }
17
+
18
+ let ctx = {
19
+ imported: false,
20
+ used: false
21
+ };
22
+
23
+ visit(ctx, ts.createSourceFile('detect.ts', code, ts.ScriptTarget.Latest, false));
24
+
25
+ return ctx.imported && ctx.used;
26
+ }
27
+
28
+ function visit(ctx: { imported: boolean; used: boolean; }, node: ts.Node): void {
29
+ if (ctx.imported && ctx.used) {
30
+ return;
31
+ }
32
+
33
+ if (
34
+ ts.isImportDeclaration(node) &&
35
+ node.importClause?.namedBindings &&
36
+ ts.isNamedImports(node.importClause.namedBindings)
37
+ ) {
38
+ let elements = node.importClause.namedBindings.elements;
39
+
40
+ for (let i = 0, n = elements.length; i < n; i++) {
41
+ let element = elements[i];
42
+
43
+ if ((element.propertyName?.text ?? element.name.text) === COMPILER_ENTRYPOINT) {
44
+ ctx.imported = true;
45
+ break;
46
+ }
47
+ }
48
+ }
49
+
50
+ if (
51
+ ts.isCallExpression(node) &&
52
+ ts.isIdentifier(node.expression) &&
53
+ node.expression.text === COMPILER_ENTRYPOINT
54
+ ) {
55
+ ctx.used = true;
56
+ }
57
+
58
+ ts.forEachChild(node, n => visit(ctx, n));
59
+ }
60
+
61
+
13
62
  const transform = (sourceFile: ts.SourceFile): TransformResult => {
14
63
  let bindings: Bindings = new Map(),
15
64
  code = sourceFile.getFullText(),
@@ -22,7 +71,7 @@ const transform = (sourceFile: ts.SourceFile): TransformResult => {
22
71
  }
23
72
 
24
73
  for (let i = 0, n = transforms.length; i < n; i++) {
25
- result = transforms[i](current, bindings, COMPILATION_NAMESPACE);
74
+ result = transforms[i](current, bindings, COMPILER_NAMESPACE);
26
75
 
27
76
  if (result !== code) {
28
77
  current = ts.createSourceFile(sourceFile.fileName, result, sourceFile.languageVersion, true);
@@ -32,7 +81,7 @@ const transform = (sourceFile: ts.SourceFile): TransformResult => {
32
81
  }
33
82
 
34
83
  if (transformed) {
35
- code = `import * as ${COMPILATION_NAMESPACE} from '@esportsplus/reactivity';\n` + code;
84
+ code = `import * as ${COMPILER_NAMESPACE} from '@esportsplus/reactivity';\n` + code;
36
85
  sourceFile = ts.createSourceFile(sourceFile.fileName, code, sourceFile.languageVersion, true);
37
86
  }
38
87
 
@@ -1,7 +1,7 @@
1
1
  import type { Plugin } from 'vite';
2
2
  import { ts } from '@esportsplus/typescript';
3
3
  import { TRANSFORM_PATTERN } from '@esportsplus/typescript/transformer';
4
- import { contains, transform } from '~/transformer';
4
+ import { transform } from '~/transformer';
5
5
  import { PACKAGE } from '~/constants';
6
6
 
7
7
 
@@ -10,7 +10,7 @@ export default (): Plugin => {
10
10
  enforce: 'pre',
11
11
  name: `${PACKAGE}/plugin-vite`,
12
12
  transform(code: string, id: string) {
13
- if (!TRANSFORM_PATTERN.test(id) || id.includes('node_modules') || !contains(code)) {
13
+ if (!TRANSFORM_PATTERN.test(id) || id.includes('node_modules')) {
14
14
  return null;
15
15
  }
16
16
 
@@ -1,6 +1,6 @@
1
1
  import { code as c, type Replacement } from '@esportsplus/typescript/transformer';
2
2
  import { ts } from '@esportsplus/typescript';
3
- import { COMPILATION_TYPE_ARRAY } from '~/constants';
3
+ import { COMPILER_TYPE_ARRAY } from '~/constants';
4
4
  import type { Bindings } from '~/types';
5
5
 
6
6
 
@@ -45,15 +45,15 @@ function isAssignmentTarget(node: ts.Node): boolean {
45
45
 
46
46
  function visit(ctx: { bindings: Bindings, replacements: Replacement[], sourceFile: ts.SourceFile }, node: ts.Node): void {
47
47
  if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer) {
48
- if (ts.isIdentifier(node.initializer) && ctx.bindings.get(node.initializer.text) === COMPILATION_TYPE_ARRAY) {
49
- ctx.bindings.set(node.name.text, COMPILATION_TYPE_ARRAY);
48
+ if (ts.isIdentifier(node.initializer) && ctx.bindings.get(node.initializer.text) === COMPILER_TYPE_ARRAY) {
49
+ ctx.bindings.set(node.name.text, COMPILER_TYPE_ARRAY);
50
50
  }
51
51
 
52
52
  if (ts.isPropertyAccessExpression(node.initializer)) {
53
53
  let path = getPropertyPath(node.initializer);
54
54
 
55
- if (path && ctx.bindings.get(path) === COMPILATION_TYPE_ARRAY) {
56
- ctx.bindings.set(node.name.text, COMPILATION_TYPE_ARRAY);
55
+ if (path && ctx.bindings.get(path) === COMPILER_TYPE_ARRAY) {
56
+ ctx.bindings.set(node.name.text, COMPILER_TYPE_ARRAY);
57
57
  }
58
58
  }
59
59
  }
@@ -68,7 +68,7 @@ function visit(ctx: { bindings: Bindings, replacements: Replacement[], sourceFil
68
68
  ts.isIdentifier(param.type.typeName) &&
69
69
  param.type.typeName.text === 'ReactiveArray'
70
70
  ) {
71
- ctx.bindings.set(param.name.text, COMPILATION_TYPE_ARRAY);
71
+ ctx.bindings.set(param.name.text, COMPILER_TYPE_ARRAY);
72
72
  }
73
73
  }
74
74
  }
@@ -80,7 +80,7 @@ function visit(ctx: { bindings: Bindings, replacements: Replacement[], sourceFil
80
80
  ) {
81
81
  let name = getExpressionName(node.expression);
82
82
 
83
- if (name && ctx.bindings.get(name) === COMPILATION_TYPE_ARRAY) {
83
+ if (name && ctx.bindings.get(name) === COMPILER_TYPE_ARRAY) {
84
84
  let objText = node.expression.getText(ctx.sourceFile);
85
85
 
86
86
  ctx.replacements.push({
@@ -99,7 +99,7 @@ function visit(ctx: { bindings: Bindings, replacements: Replacement[], sourceFil
99
99
  let elemAccess = node.left,
100
100
  objName = getExpressionName(elemAccess.expression);
101
101
 
102
- if (objName && ctx.bindings.get(objName) === COMPILATION_TYPE_ARRAY) {
102
+ if (objName && ctx.bindings.get(objName) === COMPILER_TYPE_ARRAY) {
103
103
  let indexText = elemAccess.argumentExpression.getText(ctx.sourceFile),
104
104
  objText = elemAccess.expression.getText(ctx.sourceFile),
105
105
  valueText = node.right.getText(ctx.sourceFile);
@@ -1,6 +1,6 @@
1
1
  import { ts } from '@esportsplus/typescript';
2
2
  import { code as c, type Replacement } from '@esportsplus/typescript/transformer';
3
- import { COMPILATION_TYPE_ARRAY, COMPILATION_TYPE_COMPUTED, COMPILATION_TYPE_SIGNAL, PACKAGE } from '~/constants';
3
+ import { COMPILER_TYPE_ARRAY, COMPILER_TYPE_COMPUTED, COMPILER_TYPE_SIGNAL, PACKAGE } from '~/constants';
4
4
  import type { Bindings } from '~/types';
5
5
 
6
6
 
@@ -47,7 +47,7 @@ function analyzeProperty(prop: ts.ObjectLiteralElementLike, sourceFile: ts.Sourc
47
47
  valueText = value.getText(sourceFile);
48
48
 
49
49
  if (ts.isArrowFunction(value) || ts.isFunctionExpression(value)) {
50
- return { key, type: COMPILATION_TYPE_COMPUTED, valueText };
50
+ return { key, type: COMPILER_TYPE_COMPUTED, valueText };
51
51
  }
52
52
 
53
53
  if (ts.isArrayLiteralExpression(value)) {
@@ -62,10 +62,10 @@ function analyzeProperty(prop: ts.ObjectLiteralElementLike, sourceFile: ts.Sourc
62
62
  elementsText += elements[i].getText(sourceFile);
63
63
  }
64
64
 
65
- return { key, type: COMPILATION_TYPE_ARRAY, valueText: elementsText };
65
+ return { key, type: COMPILER_TYPE_ARRAY, valueText: elementsText };
66
66
  }
67
67
 
68
- return { key, type: COMPILATION_TYPE_SIGNAL, valueText };
68
+ return { key, type: COMPILER_TYPE_SIGNAL, valueText };
69
69
  }
70
70
 
71
71
  function buildClassCode(className: string, properties: AnalyzedProperty[], ns: string): string {
@@ -79,18 +79,18 @@ function buildClassCode(className: string, properties: AnalyzedProperty[], ns: s
79
79
  for (let i = 0, n = properties.length; i < n; i++) {
80
80
  let { key, type, valueText } = properties[i];
81
81
 
82
- if (type === COMPILATION_TYPE_SIGNAL) {
82
+ if (type === COMPILER_TYPE_SIGNAL) {
83
83
  let param = `_v${paramCounter++}`;
84
84
 
85
85
  fields.push(`#${key} = ${ns}.signal(${valueText});`);
86
86
  accessors.push(`get ${key}() { return ${ns}.read(this.#${key}); }`);
87
87
  accessors.push(`set ${key}(${param}) { ${ns}.write(this.#${key}, ${param}); }`);
88
88
  }
89
- else if (type === COMPILATION_TYPE_ARRAY) {
89
+ else if (type === COMPILER_TYPE_ARRAY) {
90
90
  fields.push(`${key} = new ${ns}.ReactiveArray(${valueText});`);
91
91
  disposeStatements.push(`this.${key}.dispose();`);
92
92
  }
93
- else if (type === COMPILATION_TYPE_COMPUTED) {
93
+ else if (type === COMPILER_TYPE_COMPUTED) {
94
94
  fields.push(`#${key} = null;`);
95
95
  accessors.push(`get ${key}() { return ${ns}.read(this.#${key} ??= ${ns}.computed(${valueText})); }`);
96
96
  disposeStatements.push(`if (this.#${key}) ${ns}.dispose(this.#${key});`);
@@ -167,8 +167,8 @@ function visit(ctx: TransformContext, node: ts.Node): void {
167
167
 
168
168
  properties.push(analyzed);
169
169
 
170
- if (analyzed.type === COMPILATION_TYPE_ARRAY && varName) {
171
- ctx.bindings.set(`${varName}.${analyzed.key}`, COMPILATION_TYPE_ARRAY);
170
+ if (analyzed.type === COMPILER_TYPE_ARRAY && varName) {
171
+ ctx.bindings.set(`${varName}.${analyzed.key}`, COMPILER_TYPE_ARRAY);
172
172
  }
173
173
  }
174
174
 
@@ -1,7 +1,7 @@
1
1
  import { ts } from '@esportsplus/typescript';
2
2
  import { code as c, type Range, type Replacement } from '@esportsplus/typescript/transformer';
3
3
  import type { BindingType, Bindings } from '~/types';
4
- import { COMPILATION_TYPE_COMPUTED, COMPILATION_ENTRYPOINT, COMPILATION_TYPE_SIGNAL, PACKAGE } from '~/constants';
4
+ import { COMPILER_TYPE_COMPUTED, COMPILER_ENTRYPOINT, COMPILER_TYPE_SIGNAL, PACKAGE } from '~/constants';
5
5
 
6
6
 
7
7
  interface ArgContext {
@@ -51,14 +51,14 @@ let COMPOUND_OPERATORS = new Map<ts.SyntaxKind, string>([
51
51
 
52
52
  function classifyReactiveArg(arg: ts.Expression): BindingType | null {
53
53
  if (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg)) {
54
- return COMPILATION_TYPE_COMPUTED;
54
+ return COMPILER_TYPE_COMPUTED;
55
55
  }
56
56
 
57
57
  if (ts.isObjectLiteralExpression(arg) || ts.isArrayLiteralExpression(arg)) {
58
58
  return null;
59
59
  }
60
60
 
61
- return COMPILATION_TYPE_SIGNAL;
61
+ return COMPILER_TYPE_SIGNAL;
62
62
  }
63
63
 
64
64
  function findBinding(bindings: ScopeBinding[], name: string, node: ts.Node): ScopeBinding | undefined {
@@ -137,7 +137,7 @@ function isReactiveReassignment(node: ts.Node): boolean {
137
137
  parent.right === node &&
138
138
  ts.isCallExpression(node) &&
139
139
  ts.isIdentifier((node as ts.CallExpression).expression) &&
140
- ((node as ts.CallExpression).expression as ts.Identifier).text === COMPILATION_ENTRYPOINT
140
+ ((node as ts.CallExpression).expression as ts.Identifier).text === COMPILER_ENTRYPOINT
141
141
  ) {
142
142
  return true;
143
143
  }
@@ -181,7 +181,7 @@ function visit(ctx: TransformContext, node: ts.Node): void {
181
181
 
182
182
  if (clause?.namedBindings && ts.isNamedImports(clause.namedBindings)) {
183
183
  for (let i = 0, n = clause.namedBindings.elements.length; i < n; i++) {
184
- if (clause.namedBindings.elements[i].name.text === COMPILATION_ENTRYPOINT) {
184
+ if (clause.namedBindings.elements[i].name.text === COMPILER_ENTRYPOINT) {
185
185
  ctx.hasReactiveImport = true;
186
186
  break;
187
187
  }
@@ -193,7 +193,7 @@ function visit(ctx: TransformContext, node: ts.Node): void {
193
193
  ctx.hasReactiveImport &&
194
194
  ts.isCallExpression(node) &&
195
195
  ts.isIdentifier(node.expression) &&
196
- node.expression.text === COMPILATION_ENTRYPOINT &&
196
+ node.expression.text === COMPILER_ENTRYPOINT &&
197
197
  node.arguments.length > 0
198
198
  ) {
199
199
  let arg = node.arguments[0],
@@ -221,7 +221,7 @@ function visit(ctx: TransformContext, node: ts.Node): void {
221
221
  ctx.bindings.set(varName, classification);
222
222
  }
223
223
 
224
- if (classification === COMPILATION_TYPE_COMPUTED) {
224
+ if (classification === COMPILER_TYPE_COMPUTED) {
225
225
  let argStart = arg.getStart(ctx.sourceFile);
226
226
 
227
227
  ctx.computedArgRanges.push({ end: arg.end, start: argStart });
@@ -278,7 +278,7 @@ function visit(ctx: TransformContext, node: ts.Node): void {
278
278
  let writeCtx = isWriteContext(node);
279
279
 
280
280
  if (writeCtx) {
281
- if (binding.type !== COMPILATION_TYPE_COMPUTED) {
281
+ if (binding.type !== COMPILER_TYPE_COMPUTED) {
282
282
  let parent = node.parent;
283
283
 
284
284
  if (writeCtx === 'simple' && ts.isBinaryExpression(parent)) {
@@ -1,2 +0,0 @@
1
- declare const contains: (code: string) => boolean;
2
- export { contains };
@@ -1,38 +0,0 @@
1
- import { code as c } from '@esportsplus/typescript/transformer';
2
- import { ts } from '@esportsplus/typescript';
3
- import { COMPILATION_ENTRYPOINT, COMPILATION_ENTRYPOINT_REGEX } from '../constants.js';
4
- function visit(ctx, node) {
5
- if (ctx.imported && ctx.used) {
6
- return;
7
- }
8
- if (ts.isImportDeclaration(node) &&
9
- node.importClause?.namedBindings &&
10
- ts.isNamedImports(node.importClause.namedBindings)) {
11
- let elements = node.importClause.namedBindings.elements;
12
- for (let i = 0, n = elements.length; i < n; i++) {
13
- let element = elements[i];
14
- if ((element.propertyName?.text ?? element.name.text) === COMPILATION_ENTRYPOINT) {
15
- ctx.imported = true;
16
- break;
17
- }
18
- }
19
- }
20
- if (ts.isCallExpression(node) &&
21
- ts.isIdentifier(node.expression) &&
22
- node.expression.text === COMPILATION_ENTRYPOINT) {
23
- ctx.used = true;
24
- }
25
- ts.forEachChild(node, n => visit(ctx, n));
26
- }
27
- const contains = (code) => {
28
- if (!c.contains(code, { regex: COMPILATION_ENTRYPOINT_REGEX })) {
29
- return false;
30
- }
31
- let ctx = {
32
- imported: false,
33
- used: false
34
- };
35
- visit(ctx, ts.createSourceFile('detect.ts', code, ts.ScriptTarget.Latest, false));
36
- return ctx.imported && ctx.used;
37
- };
38
- export { contains };
@@ -1,56 +0,0 @@
1
- import { code as c } from '@esportsplus/typescript/transformer';
2
- import { ts } from '@esportsplus/typescript';
3
- import { COMPILATION_ENTRYPOINT, COMPILATION_ENTRYPOINT_REGEX } from '~/constants';
4
-
5
-
6
- function visit(ctx: { imported: boolean; used: boolean; }, node: ts.Node): void {
7
- if (ctx.imported && ctx.used) {
8
- return;
9
- }
10
-
11
- if (
12
- ts.isImportDeclaration(node) &&
13
- node.importClause?.namedBindings &&
14
- ts.isNamedImports(node.importClause.namedBindings)
15
- ) {
16
- let elements = node.importClause.namedBindings.elements;
17
-
18
- for (let i = 0, n = elements.length; i < n; i++) {
19
- let element = elements[i];
20
-
21
- if ((element.propertyName?.text ?? element.name.text) === COMPILATION_ENTRYPOINT) {
22
- ctx.imported = true;
23
- break;
24
- }
25
- }
26
- }
27
-
28
- if (
29
- ts.isCallExpression(node) &&
30
- ts.isIdentifier(node.expression) &&
31
- node.expression.text === COMPILATION_ENTRYPOINT
32
- ) {
33
- ctx.used = true;
34
- }
35
-
36
- ts.forEachChild(node, n => visit(ctx, n));
37
- }
38
-
39
-
40
- const contains = (code: string): boolean => {
41
- if (!c.contains(code, { regex: COMPILATION_ENTRYPOINT_REGEX })) {
42
- return false;
43
- }
44
-
45
- let ctx = {
46
- imported: false,
47
- used: false
48
- };
49
-
50
- visit(ctx, ts.createSourceFile('detect.ts', code, ts.ScriptTarget.Latest, false));
51
-
52
- return ctx.imported && ctx.used;
53
- };
54
-
55
-
56
- export { contains };