@esportsplus/reactivity 0.22.3 → 0.23.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 (56) hide show
  1. package/build/index.d.ts +1 -1
  2. package/build/index.js +1 -1
  3. package/build/reactive/array.d.ts +3 -0
  4. package/build/reactive/array.js +32 -2
  5. package/build/reactive/index.d.ts +17 -14
  6. package/build/reactive/index.js +7 -25
  7. package/build/system.js +1 -1
  8. package/build/transformer/core/detector.d.ts +2 -0
  9. package/build/transformer/core/detector.js +6 -0
  10. package/build/transformer/core/index.d.ts +10 -0
  11. package/build/transformer/core/index.js +55 -0
  12. package/build/transformer/core/transforms/auto-dispose.d.ts +3 -0
  13. package/build/transformer/core/transforms/auto-dispose.js +116 -0
  14. package/build/transformer/core/transforms/reactive-array.d.ts +4 -0
  15. package/build/transformer/core/transforms/reactive-array.js +89 -0
  16. package/build/transformer/core/transforms/reactive-object.d.ts +4 -0
  17. package/build/transformer/core/transforms/reactive-object.js +155 -0
  18. package/build/transformer/core/transforms/reactive-primitives.d.ts +4 -0
  19. package/build/transformer/core/transforms/reactive-primitives.js +325 -0
  20. package/build/transformer/core/transforms/utilities.d.ts +9 -0
  21. package/build/transformer/core/transforms/utilities.js +57 -0
  22. package/build/transformer/plugins/esbuild.d.ts +5 -0
  23. package/build/transformer/plugins/esbuild.js +30 -0
  24. package/build/transformer/plugins/tsc.d.ts +3 -0
  25. package/build/transformer/plugins/tsc.js +4 -0
  26. package/build/transformer/plugins/vite.d.ts +5 -0
  27. package/build/transformer/plugins/vite.js +28 -0
  28. package/build/types.d.ts +14 -4
  29. package/package.json +34 -3
  30. package/readme.md +276 -2
  31. package/src/constants.ts +1 -1
  32. package/src/index.ts +1 -1
  33. package/src/reactive/array.ts +49 -2
  34. package/src/reactive/index.ts +33 -57
  35. package/src/system.ts +14 -5
  36. package/src/transformer/core/detector.ts +12 -0
  37. package/src/transformer/core/index.ts +82 -0
  38. package/src/transformer/core/transforms/auto-dispose.ts +194 -0
  39. package/src/transformer/core/transforms/reactive-array.ts +140 -0
  40. package/src/transformer/core/transforms/reactive-object.ts +244 -0
  41. package/src/transformer/core/transforms/reactive-primitives.ts +459 -0
  42. package/src/transformer/core/transforms/utilities.ts +95 -0
  43. package/src/transformer/plugins/esbuild.ts +46 -0
  44. package/src/transformer/plugins/tsc.ts +8 -0
  45. package/src/transformer/plugins/vite.ts +41 -0
  46. package/src/types.ts +24 -5
  47. package/test/arrays.ts +146 -0
  48. package/test/effects.ts +168 -0
  49. package/test/index.ts +8 -0
  50. package/test/nested.ts +201 -0
  51. package/test/objects.ts +106 -0
  52. package/test/primitives.ts +171 -0
  53. package/test/vite.config.ts +40 -0
  54. package/build/reactive/object.d.ts +0 -7
  55. package/build/reactive/object.js +0 -79
  56. package/src/reactive/object.ts +0 -116
@@ -0,0 +1,325 @@
1
+ import { uid } from '@esportsplus/typescript/transformer';
2
+ import ts from 'typescript';
3
+ import { addMissingImports, applyReplacements } from './utilities.js';
4
+ function findEnclosingScope(node) {
5
+ let current = node.parent;
6
+ while (current) {
7
+ if (ts.isBlock(current) ||
8
+ ts.isSourceFile(current) ||
9
+ ts.isFunctionDeclaration(current) ||
10
+ ts.isFunctionExpression(current) ||
11
+ ts.isArrowFunction(current) ||
12
+ ts.isForStatement(current) ||
13
+ ts.isForInStatement(current) ||
14
+ ts.isForOfStatement(current)) {
15
+ return current;
16
+ }
17
+ current = current.parent;
18
+ }
19
+ return node.getSourceFile();
20
+ }
21
+ function findBinding(bindings, name, node) {
22
+ for (let i = 0, n = bindings.length; i < n; i++) {
23
+ let b = bindings[i];
24
+ if (b.name === name && isInScope(node, b)) {
25
+ return b;
26
+ }
27
+ }
28
+ return undefined;
29
+ }
30
+ function isInComputedRange(ranges, start, end) {
31
+ for (let i = 0, n = ranges.length; i < n; i++) {
32
+ let r = ranges[i];
33
+ if (start >= r.start && end <= r.end) {
34
+ return true;
35
+ }
36
+ }
37
+ return false;
38
+ }
39
+ function isInScope(reference, binding) {
40
+ let current = reference;
41
+ while (current) {
42
+ if (current === binding.scope) {
43
+ return true;
44
+ }
45
+ current = current.parent;
46
+ }
47
+ return false;
48
+ }
49
+ function classifyReactiveArg(arg) {
50
+ if (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg)) {
51
+ return 'computed';
52
+ }
53
+ if (ts.isObjectLiteralExpression(arg) || ts.isArrayLiteralExpression(arg)) {
54
+ return null;
55
+ }
56
+ return 'signal';
57
+ }
58
+ function isInDeclarationInit(node) {
59
+ let parent = node.parent;
60
+ if (ts.isVariableDeclaration(parent) && parent.initializer === node) {
61
+ return true;
62
+ }
63
+ return false;
64
+ }
65
+ function isReactiveReassignment(node) {
66
+ let parent = node.parent;
67
+ if (ts.isBinaryExpression(parent) &&
68
+ parent.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
69
+ parent.right === node &&
70
+ ts.isCallExpression(node) &&
71
+ ts.isIdentifier(node.expression) &&
72
+ node.expression.text === 'reactive') {
73
+ return true;
74
+ }
75
+ return false;
76
+ }
77
+ function isWriteContext(node) {
78
+ let parent = node.parent;
79
+ if (ts.isBinaryExpression(parent) && parent.left === node) {
80
+ let op = parent.operatorToken.kind;
81
+ if (op === ts.SyntaxKind.EqualsToken) {
82
+ return 'simple';
83
+ }
84
+ if (op >= ts.SyntaxKind.PlusEqualsToken && op <= ts.SyntaxKind.CaretEqualsToken) {
85
+ return 'compound';
86
+ }
87
+ if (op === ts.SyntaxKind.AmpersandAmpersandEqualsToken ||
88
+ op === ts.SyntaxKind.BarBarEqualsToken ||
89
+ op === ts.SyntaxKind.QuestionQuestionEqualsToken) {
90
+ return 'compound';
91
+ }
92
+ }
93
+ if (ts.isPostfixUnaryExpression(parent) || ts.isPrefixUnaryExpression(parent)) {
94
+ let op = parent.operator;
95
+ if (op === ts.SyntaxKind.PlusPlusToken || op === ts.SyntaxKind.MinusMinusToken) {
96
+ return 'increment';
97
+ }
98
+ }
99
+ return false;
100
+ }
101
+ function getCompoundOperator(kind) {
102
+ if (kind === ts.SyntaxKind.PlusEqualsToken) {
103
+ return '+';
104
+ }
105
+ else if (kind === ts.SyntaxKind.MinusEqualsToken) {
106
+ return '-';
107
+ }
108
+ else if (kind === ts.SyntaxKind.AsteriskEqualsToken) {
109
+ return '*';
110
+ }
111
+ else if (kind === ts.SyntaxKind.SlashEqualsToken) {
112
+ return '/';
113
+ }
114
+ else if (kind === ts.SyntaxKind.PercentEqualsToken) {
115
+ return '%';
116
+ }
117
+ else if (kind === ts.SyntaxKind.AsteriskAsteriskEqualsToken) {
118
+ return '**';
119
+ }
120
+ else if (kind === ts.SyntaxKind.AmpersandEqualsToken) {
121
+ return '&';
122
+ }
123
+ else if (kind === ts.SyntaxKind.BarEqualsToken) {
124
+ return '|';
125
+ }
126
+ else if (kind === ts.SyntaxKind.CaretEqualsToken) {
127
+ return '^';
128
+ }
129
+ else if (kind === ts.SyntaxKind.LessThanLessThanEqualsToken) {
130
+ return '<<';
131
+ }
132
+ else if (kind === ts.SyntaxKind.GreaterThanGreaterThanEqualsToken) {
133
+ return '>>';
134
+ }
135
+ else if (kind === ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken) {
136
+ return '>>>';
137
+ }
138
+ else if (kind === ts.SyntaxKind.AmpersandAmpersandEqualsToken) {
139
+ return '&&';
140
+ }
141
+ else if (kind === ts.SyntaxKind.BarBarEqualsToken) {
142
+ return '||';
143
+ }
144
+ else if (kind === ts.SyntaxKind.QuestionQuestionEqualsToken) {
145
+ return '??';
146
+ }
147
+ else {
148
+ return '+';
149
+ }
150
+ }
151
+ function transformComputedArg(arg, scopedBindings, sourceFile, neededImports) {
152
+ let argStart = arg.getStart(sourceFile), innerReplacements = [], text = arg.getText(sourceFile);
153
+ function visitArg(node) {
154
+ if (ts.isIdentifier(node)) {
155
+ if (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) {
156
+ ts.forEachChild(node, visitArg);
157
+ return;
158
+ }
159
+ if (ts.isCallExpression(node.parent) && node.parent.expression === node) {
160
+ ts.forEachChild(node, visitArg);
161
+ return;
162
+ }
163
+ let binding = findBinding(scopedBindings, node.text, node);
164
+ if (binding) {
165
+ neededImports.add('read');
166
+ innerReplacements.push({
167
+ end: node.end - argStart,
168
+ newText: `read(${node.text})`,
169
+ start: node.getStart(sourceFile) - argStart
170
+ });
171
+ }
172
+ }
173
+ ts.forEachChild(node, visitArg);
174
+ }
175
+ visitArg(arg);
176
+ return applyReplacements(text, innerReplacements);
177
+ }
178
+ const transformReactivePrimitives = (sourceFile, bindings) => {
179
+ let code = sourceFile.getFullText(), computedArgRanges = [], hasReactiveImport = false, neededImports = new Set(), replacements = [], scopedBindings = [];
180
+ function visit(node) {
181
+ if (ts.isImportDeclaration(node) &&
182
+ ts.isStringLiteral(node.moduleSpecifier) &&
183
+ node.moduleSpecifier.text.includes('@esportsplus/reactivity')) {
184
+ let clause = node.importClause;
185
+ if (clause?.namedBindings && ts.isNamedImports(clause.namedBindings)) {
186
+ for (let i = 0, n = clause.namedBindings.elements.length; i < n; i++) {
187
+ if (clause.namedBindings.elements[i].name.text === 'reactive') {
188
+ hasReactiveImport = true;
189
+ break;
190
+ }
191
+ }
192
+ }
193
+ }
194
+ if (hasReactiveImport &&
195
+ ts.isCallExpression(node) &&
196
+ ts.isIdentifier(node.expression) &&
197
+ node.expression.text === 'reactive' &&
198
+ node.arguments.length > 0) {
199
+ let arg = node.arguments[0], classification = classifyReactiveArg(arg);
200
+ if (classification) {
201
+ let varName = null;
202
+ if (ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name)) {
203
+ varName = node.parent.name.text;
204
+ }
205
+ else if (ts.isBinaryExpression(node.parent) &&
206
+ node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
207
+ ts.isIdentifier(node.parent.left)) {
208
+ varName = node.parent.left.text;
209
+ }
210
+ if (varName) {
211
+ let scope = findEnclosingScope(node);
212
+ scopedBindings.push({ name: varName, scope, type: classification });
213
+ bindings.set(varName, classification);
214
+ }
215
+ if (classification === 'computed') {
216
+ computedArgRanges.push({
217
+ end: arg.end,
218
+ start: arg.getStart(sourceFile)
219
+ });
220
+ let argText = transformComputedArg(arg, scopedBindings, sourceFile, neededImports);
221
+ replacements.push({
222
+ end: node.end,
223
+ newText: `computed(${argText})`,
224
+ start: node.pos
225
+ });
226
+ neededImports.add('computed');
227
+ }
228
+ else {
229
+ let argText = arg.getText(sourceFile);
230
+ replacements.push({
231
+ end: node.end,
232
+ newText: `signal(${argText})`,
233
+ start: node.pos
234
+ });
235
+ neededImports.add('signal');
236
+ }
237
+ }
238
+ }
239
+ if (ts.isIdentifier(node) && !isInDeclarationInit(node.parent)) {
240
+ if (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) {
241
+ ts.forEachChild(node, visit);
242
+ return;
243
+ }
244
+ let nodeStart = node.getStart(sourceFile);
245
+ let insideComputedArg = isInComputedRange(computedArgRanges, nodeStart, node.end);
246
+ if (insideComputedArg) {
247
+ ts.forEachChild(node, visit);
248
+ return;
249
+ }
250
+ let binding = findBinding(scopedBindings, node.text, node), name = node.text;
251
+ if (binding) {
252
+ if (!isReactiveReassignment(node.parent) &&
253
+ !(ts.isTypeOfExpression(node.parent) && node.parent.expression === node)) {
254
+ let writeCtx = isWriteContext(node);
255
+ if (writeCtx) {
256
+ if (binding.type !== 'computed') {
257
+ neededImports.add('set');
258
+ let parent = node.parent;
259
+ if (writeCtx === 'simple' && ts.isBinaryExpression(parent)) {
260
+ let valueText = parent.right.getText(sourceFile);
261
+ replacements.push({
262
+ end: parent.end,
263
+ newText: `set(${name}, ${valueText})`,
264
+ start: parent.pos
265
+ });
266
+ }
267
+ else if (writeCtx === 'compound' && ts.isBinaryExpression(parent)) {
268
+ let op = getCompoundOperator(parent.operatorToken.kind), valueText = parent.right.getText(sourceFile);
269
+ replacements.push({
270
+ end: parent.end,
271
+ newText: `set(${name}, ${name}.value ${op} ${valueText})`,
272
+ start: parent.pos
273
+ });
274
+ }
275
+ else if (writeCtx === 'increment') {
276
+ let isPrefix = ts.isPrefixUnaryExpression(parent), op = parent.operator, delta = op === ts.SyntaxKind.PlusPlusToken ? '+ 1' : '- 1';
277
+ if (ts.isExpressionStatement(parent.parent)) {
278
+ replacements.push({
279
+ end: parent.end,
280
+ newText: `set(${name}, ${name}.value ${delta})`,
281
+ start: parent.pos
282
+ });
283
+ }
284
+ else if (isPrefix) {
285
+ replacements.push({
286
+ end: parent.end,
287
+ newText: `(set(${name}, ${name}.value ${delta}), ${name}.value)`,
288
+ start: parent.pos
289
+ });
290
+ }
291
+ else {
292
+ let tmp = uid('tmp');
293
+ replacements.push({
294
+ end: parent.end,
295
+ newText: `((${tmp}) => (set(${name}, ${tmp} ${delta}), ${tmp}))(${name}.value)`,
296
+ start: parent.pos
297
+ });
298
+ }
299
+ }
300
+ }
301
+ }
302
+ else {
303
+ neededImports.add('read');
304
+ replacements.push({
305
+ end: node.end,
306
+ newText: `read(${name})`,
307
+ start: node.pos
308
+ });
309
+ }
310
+ }
311
+ }
312
+ }
313
+ ts.forEachChild(node, visit);
314
+ }
315
+ visit(sourceFile);
316
+ if (replacements.length === 0) {
317
+ return code;
318
+ }
319
+ let result = applyReplacements(code, replacements);
320
+ if (neededImports.size > 0) {
321
+ result = addMissingImports(result, neededImports);
322
+ }
323
+ return result;
324
+ };
325
+ export { transformReactivePrimitives };
@@ -0,0 +1,9 @@
1
+ import type { Replacement } from '@esportsplus/typescript/transformer';
2
+ import { applyReplacements } from '@esportsplus/typescript/transformer';
3
+ type ExtraImport = {
4
+ module: string;
5
+ specifier: string;
6
+ };
7
+ declare const addMissingImports: (code: string, needed: Set<string>, extraImports?: ExtraImport[]) => string;
8
+ export { addMissingImports, applyReplacements };
9
+ export type { ExtraImport, Replacement };
@@ -0,0 +1,57 @@
1
+ import { applyReplacements } from '@esportsplus/typescript/transformer';
2
+ const BRACES_CONTENT_REGEX = /\{([^}]*)\}/;
3
+ const REACTIVITY_IMPORT_REGEX = /(import\s*\{[^}]*\}\s*from\s*['"]@esportsplus\/reactivity['"])/;
4
+ const addMissingImports = (code, needed, extraImports) => {
5
+ let reactivityImportMatch = code.match(REACTIVITY_IMPORT_REGEX);
6
+ if (!reactivityImportMatch) {
7
+ return code;
8
+ }
9
+ let bracesMatch = reactivityImportMatch[1].match(BRACES_CONTENT_REGEX), existing = new Set(), existingImport = reactivityImportMatch[1], extraSpecifiers = new Set(), toAdd = [];
10
+ if (bracesMatch?.[1]) {
11
+ let parts = bracesMatch[1].split(',');
12
+ for (let i = 0, n = parts.length; i < n; i++) {
13
+ let trimmed = parts[i].trim();
14
+ if (trimmed) {
15
+ existing.add(trimmed);
16
+ }
17
+ }
18
+ }
19
+ if (extraImports) {
20
+ for (let i = 0, n = extraImports.length; i < n; i++) {
21
+ extraSpecifiers.add(extraImports[i].specifier);
22
+ }
23
+ }
24
+ for (let imp of needed) {
25
+ if (!extraSpecifiers.has(imp) && !existing.has(imp)) {
26
+ toAdd.push(imp);
27
+ }
28
+ }
29
+ if (toAdd.length > 0) {
30
+ let combined = [];
31
+ for (let item of existing) {
32
+ if (item) {
33
+ combined.push(item);
34
+ }
35
+ }
36
+ for (let i = 0, n = toAdd.length; i < n; i++) {
37
+ if (toAdd[i]) {
38
+ combined.push(toAdd[i]);
39
+ }
40
+ }
41
+ combined.sort();
42
+ code = code.replace(existingImport, existingImport.replace(BRACES_CONTENT_REGEX, `{ ${combined.join(', ')} }`));
43
+ }
44
+ if (extraImports) {
45
+ for (let i = 0, n = extraImports.length; i < n; i++) {
46
+ let extra = extraImports[i];
47
+ if (needed.has(extra.specifier) && !code.includes(extra.module)) {
48
+ let insertPos = code.indexOf('import');
49
+ code = code.substring(0, insertPos) +
50
+ `import { ${extra.specifier} } from '${extra.module}';\n` +
51
+ code.substring(insertPos);
52
+ }
53
+ }
54
+ }
55
+ return code;
56
+ };
57
+ export { addMissingImports, applyReplacements };
@@ -0,0 +1,5 @@
1
+ import type { Plugin } from 'esbuild';
2
+ import type { TransformOptions } from '../../types.js';
3
+ declare const _default: (options?: TransformOptions) => Plugin;
4
+ export default _default;
5
+ export type { TransformOptions as PluginOptions };
@@ -0,0 +1,30 @@
1
+ import { mightNeedTransform, transform } from '../../transformer/core/index.js';
2
+ import fs from 'fs';
3
+ import ts from 'typescript';
4
+ export default (options) => {
5
+ return {
6
+ name: '@esportsplus/reactivity/plugin-esbuild',
7
+ setup(build) {
8
+ build.onLoad({ filter: /\.[tj]sx?$/ }, async (args) => {
9
+ let code = await fs.promises.readFile(args.path, 'utf8');
10
+ if (!mightNeedTransform(code)) {
11
+ return null;
12
+ }
13
+ try {
14
+ let sourceFile = ts.createSourceFile(args.path, code, ts.ScriptTarget.Latest, true), result = transform(sourceFile, options);
15
+ if (!result.transformed) {
16
+ return null;
17
+ }
18
+ return {
19
+ contents: result.code,
20
+ loader: args.path.endsWith('x') ? 'tsx' : 'ts'
21
+ };
22
+ }
23
+ catch (error) {
24
+ console.error(`@esportsplus/reactivity: Error transforming ${args.path}:`, error);
25
+ return null;
26
+ }
27
+ });
28
+ }
29
+ };
30
+ };
@@ -0,0 +1,3 @@
1
+ import ts from 'typescript';
2
+ declare const _default: (_program: ts.Program) => ts.TransformerFactory<ts.SourceFile>;
3
+ export default _default;
@@ -0,0 +1,4 @@
1
+ import { createTransformer } from '../../transformer/core/index.js';
2
+ export default (_program) => {
3
+ return createTransformer();
4
+ };
@@ -0,0 +1,5 @@
1
+ import type { Plugin } from 'vite';
2
+ import type { TransformOptions } from '../../types.js';
3
+ declare const _default: (options?: TransformOptions) => Plugin;
4
+ export default _default;
5
+ export type { TransformOptions as PluginOptions };
@@ -0,0 +1,28 @@
1
+ import { mightNeedTransform, transform } from '../../transformer/core/index.js';
2
+ import ts from 'typescript';
3
+ const TRANSFORM_PATTERN = /\.[tj]sx?$/;
4
+ export default (options) => {
5
+ return {
6
+ enforce: 'pre',
7
+ name: '@esportsplus/reactivity/plugin-vite',
8
+ transform(code, id) {
9
+ if (!TRANSFORM_PATTERN.test(id) || id.includes('node_modules')) {
10
+ return null;
11
+ }
12
+ if (!mightNeedTransform(code)) {
13
+ return null;
14
+ }
15
+ try {
16
+ let sourceFile = ts.createSourceFile(id, code, ts.ScriptTarget.Latest, true), result = transform(sourceFile, options);
17
+ if (!result.transformed) {
18
+ return null;
19
+ }
20
+ return { code: result.code, map: null };
21
+ }
22
+ catch (error) {
23
+ console.error(`@esportsplus/reactivity: Error transforming ${id}:`, error);
24
+ return null;
25
+ }
26
+ }
27
+ };
28
+ };
package/build/types.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { COMPUTED, SIGNAL, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_RECOMPUTING } from './constants.js';
2
- import { ReactiveArray } from './reactive/array.js';
3
- import { ReactiveObject } from './reactive/object.js';
2
+ import { ReactiveArray, ReactiveObject } from './reactive/index.js';
3
+ import ts from 'typescript';
4
+ type BindingType = 'array' | 'computed' | 'object' | 'signal';
5
+ type Bindings = Map<string, BindingType>;
4
6
  interface Computed<T> {
5
7
  cleanup: VoidFunction | VoidFunction[] | null;
6
8
  deps: Link | null;
@@ -17,10 +19,10 @@ interface Computed<T> {
17
19
  }
18
20
  interface Link {
19
21
  dep: Signal<unknown> | Computed<unknown>;
20
- sub: Computed<unknown>;
21
22
  nextDep: Link | null;
22
23
  nextSub: Link | null;
23
24
  prevSub: Link | null;
25
+ sub: Computed<unknown>;
24
26
  version: number;
25
27
  }
26
28
  type Signal<T> = {
@@ -29,4 +31,12 @@ type Signal<T> = {
29
31
  type: typeof SIGNAL;
30
32
  value: T;
31
33
  };
32
- export type { Computed, Link, Signal, ReactiveArray, ReactiveObject };
34
+ interface TransformOptions {
35
+ autoDispose?: boolean;
36
+ }
37
+ interface TransformResult {
38
+ code: string;
39
+ sourceFile: ts.SourceFile;
40
+ transformed: boolean;
41
+ }
42
+ export type { BindingType, Bindings, Computed, Link, ReactiveArray, ReactiveObject, Signal, TransformOptions, TransformResult };
package/package.json CHANGED
@@ -1,10 +1,40 @@
1
1
  {
2
2
  "author": "ICJR",
3
3
  "dependencies": {
4
- "@esportsplus/utilities": "^0.25.0"
4
+ "@esportsplus/utilities": "^0.27.2"
5
5
  },
6
6
  "devDependencies": {
7
- "@esportsplus/typescript": "^0.9.2"
7
+ "@esportsplus/typescript": "^0.11.0",
8
+ "@types/node": "^25.0.3",
9
+ "esbuild": "^0.27.2",
10
+ "typescript": "^5.9.3",
11
+ "vite": "^7.3.0"
12
+ },
13
+ "exports": {
14
+ ".": {
15
+ "import": "./build/index.js",
16
+ "types": "./build/index.d.ts"
17
+ },
18
+ "./constants": {
19
+ "import": "./build/constants.js",
20
+ "types": "./build/constants.d.ts"
21
+ },
22
+ "./plugins/esbuild": {
23
+ "import": "./build/plugins/esbuild.js",
24
+ "types": "./build/plugins/esbuild.d.ts"
25
+ },
26
+ "./plugins/tsc": {
27
+ "import": "./build/plugins/tsc.js",
28
+ "types": "./build/plugins/tsc.d.ts"
29
+ },
30
+ "./plugins/vite": {
31
+ "import": "./build/plugins/vite.js",
32
+ "types": "./build/plugins/vite.d.ts"
33
+ },
34
+ "./reactive/array": {
35
+ "import": "./build/reactive/array.js",
36
+ "types": "./build/reactive/array.d.ts"
37
+ }
8
38
  },
9
39
  "main": "build/index.js",
10
40
  "name": "@esportsplus/reactivity",
@@ -15,9 +45,10 @@
15
45
  },
16
46
  "type": "module",
17
47
  "types": "build/index.d.ts",
18
- "version": "0.22.3",
48
+ "version": "0.23.0",
19
49
  "scripts": {
20
50
  "build": "tsc && tsc-alias",
51
+ "build:test": "pnpm build && vite build --config test/vite.config.ts",
21
52
  "-": "-"
22
53
  }
23
54
  }