@variojs/core 0.0.1 → 0.0.2

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 (39) hide show
  1. package/README.md +31 -216
  2. package/dist/errors.js +4 -132
  3. package/dist/expression/cache.js +1 -158
  4. package/dist/expression/compiler.js +1 -141
  5. package/dist/expression/dependencies.js +1 -106
  6. package/dist/expression/evaluate.js +2 -75
  7. package/dist/expression/evaluator.js +1 -533
  8. package/dist/expression/index.js +1 -12
  9. package/dist/expression/parser.js +1 -42
  10. package/dist/expression/utils.js +1 -78
  11. package/dist/expression/whitelist.js +3 -198
  12. package/dist/index.js +1 -21
  13. package/dist/runtime/context.js +1 -7
  14. package/dist/runtime/create-context.js +1 -62
  15. package/dist/runtime/index.js +1 -10
  16. package/dist/runtime/loop-context-pool.js +1 -114
  17. package/dist/runtime/path.js +1 -302
  18. package/dist/runtime/proxy.js +1 -54
  19. package/dist/runtime/sandbox.js +1 -32
  20. package/dist/types.js +1 -20
  21. package/dist/vm/errors.js +1 -5
  22. package/dist/vm/executor.js +2 -137
  23. package/dist/vm/handlers/array/pop.js +1 -28
  24. package/dist/vm/handlers/array/push.js +1 -42
  25. package/dist/vm/handlers/array/shift.js +1 -28
  26. package/dist/vm/handlers/array/splice.js +1 -59
  27. package/dist/vm/handlers/array/unshift.js +1 -42
  28. package/dist/vm/handlers/array/utils.js +1 -33
  29. package/dist/vm/handlers/batch.js +1 -40
  30. package/dist/vm/handlers/call.js +1 -65
  31. package/dist/vm/handlers/emit.js +1 -26
  32. package/dist/vm/handlers/if.js +1 -35
  33. package/dist/vm/handlers/index.js +1 -55
  34. package/dist/vm/handlers/log.js +1 -41
  35. package/dist/vm/handlers/loop.js +1 -71
  36. package/dist/vm/handlers/navigate.js +1 -43
  37. package/dist/vm/handlers/set.js +1 -30
  38. package/dist/vm/index.js +1 -7
  39. package/package.json +2 -2
@@ -1,59 +1 @@
1
- /**
2
- * splice 动作处理器
3
- *
4
- * 功能:删除或替换数组元素
5
- * 示例:{ "type": "splice", "path": "items", "start": 0, "deleteCount": 1, "items": "{{ newItem }}" }
6
- */
7
- import { ActionError, ErrorCodes } from '../../../errors.js';
8
- import { evaluate } from '../../../expression/evaluate.js';
9
- import { invalidateCache } from '../../../expression/cache.js';
10
- import { evaluateExpressionsRecursively } from './utils.js';
11
- /**
12
- * 处理 splice 动作
13
- */
14
- export async function handleSplice(ctx, action) {
15
- const { path, start, deleteCount = 0, items } = action;
16
- if (!path || typeof path !== 'string') {
17
- throw new ActionError(action, 'splice action requires "path" parameter', ErrorCodes.ACTION_MISSING_PARAM, { metadata: { param: 'path' } });
18
- }
19
- // 获取数组
20
- const array = ctx._get(path);
21
- if (!Array.isArray(array)) {
22
- throw new ActionError(action, `Path "${path}" does not point to an array`, ErrorCodes.ACTION_INVALID_PARAM, { metadata: { param: 'path', path, actualType: typeof array } });
23
- }
24
- // 求值 start(支持表达式)
25
- let finalStart;
26
- if (typeof start === 'string' && start.startsWith('{{') && start.endsWith('}}')) {
27
- const expr = start.slice(2, -2).trim();
28
- finalStart = Number(evaluate(expr, ctx));
29
- }
30
- else {
31
- finalStart = Number(start);
32
- }
33
- // 求值 deleteCount(支持表达式)
34
- let finalDeleteCount;
35
- if (typeof deleteCount === 'string' && deleteCount.startsWith('{{') && deleteCount.endsWith('}}')) {
36
- const expr = deleteCount.slice(2, -2).trim();
37
- finalDeleteCount = Number(evaluate(expr, ctx));
38
- }
39
- else {
40
- finalDeleteCount = Number(deleteCount);
41
- }
42
- // 求值 items(支持递归表达式)
43
- let finalItems = [];
44
- if (items != null) {
45
- const evaluated = evaluateExpressionsRecursively(items, ctx);
46
- if (Array.isArray(evaluated)) {
47
- finalItems = evaluated;
48
- }
49
- else {
50
- finalItems = [evaluated];
51
- }
52
- }
53
- // 执行 splice
54
- array.splice(finalStart, finalDeleteCount, ...finalItems);
55
- // 使相关缓存失效
56
- invalidateCache(path, ctx);
57
- invalidateCache(`${path}.*`, ctx);
58
- }
59
- //# sourceMappingURL=splice.js.map
1
+ import{ActionError as f,ErrorCodes as u}from"../../../errors.js";import{evaluate as h}from"../../../expression/evaluate.js";import{invalidateCache as y}from"../../../expression/cache.js";import{evaluateExpressionsRecursively as A}from"./utils.js";async function C(r,s){const{path:e,start:a,deleteCount:i=0,items:m}=s;if(!e||typeof e!="string")throw new f(s,'splice action requires "path" parameter',u.ACTION_MISSING_PARAM,{metadata:{param:"path"}});const o=r._get(e);if(!Array.isArray(o))throw new f(s,`Path "${e}" does not point to an array`,u.ACTION_INVALID_PARAM,{metadata:{param:"path",path:e,actualType:typeof o}});let n;if(typeof a=="string"&&a.startsWith("{{")&&a.endsWith("}}")){const t=a.slice(2,-2).trim();n=Number(h(t,r))}else n=Number(a);let l;if(typeof i=="string"&&i.startsWith("{{")&&i.endsWith("}}")){const t=i.slice(2,-2).trim();l=Number(h(t,r))}else l=Number(i);let p=[];if(m!=null){const t=A(m,r);Array.isArray(t)?p=t:p=[t]}o.splice(n,l,...p),y(e,r),y(`${e}.*`,r)}export{C as handleSplice};
@@ -1,42 +1 @@
1
- /**
2
- * unshift 动作处理器
3
- *
4
- * 功能:添加元素到数组开头
5
- * 示例:{ "type": "unshift", "path": "items", "value": "{{ firstItem }}" }
6
- * 示例:{ "type": "unshift", "path": "todos", "items": [{ text: "{{ newTodo }}", done: false }] }
7
- */
8
- import { ActionError, ErrorCodes } from '../../../errors.js';
9
- import { invalidateCache } from '../../../expression/cache.js';
10
- import { evaluateExpressionsRecursively } from './utils.js';
11
- /**
12
- * 处理 unshift 动作
13
- */
14
- export async function handleUnshift(ctx, action) {
15
- const { path, value, items } = action;
16
- if (!path || typeof path !== 'string') {
17
- throw new ActionError(action, 'unshift action requires "path" parameter', ErrorCodes.ACTION_MISSING_PARAM, { metadata: { param: 'path' } });
18
- }
19
- // 获取数组
20
- const array = ctx._get(path);
21
- if (!Array.isArray(array)) {
22
- throw new ActionError(action, `Path "${path}" does not point to an array`, ErrorCodes.ACTION_INVALID_PARAM, { metadata: { param: 'path', path, actualType: typeof array } });
23
- }
24
- // 支持 items 作为 value 的别名
25
- const inputValue = items !== undefined ? items : value;
26
- if (inputValue === undefined) {
27
- throw new ActionError(action, 'unshift action requires "value" or "items" parameter', ErrorCodes.ACTION_MISSING_PARAM, { metadata: { param: 'value|items' } });
28
- }
29
- // 递归求值表达式(支持对象/数组中的表达式)
30
- const finalValue = evaluateExpressionsRecursively(inputValue, ctx);
31
- // 如果是数组,展开添加
32
- if (Array.isArray(finalValue)) {
33
- array.unshift(...finalValue);
34
- }
35
- else {
36
- array.unshift(finalValue);
37
- }
38
- // 使相关缓存失效
39
- invalidateCache(path, ctx);
40
- invalidateCache(`${path}.*`, ctx);
41
- }
42
- //# sourceMappingURL=unshift.js.map
1
+ import{ActionError as n,ErrorCodes as o}from"../../../errors.js";import{invalidateCache as f}from"../../../expression/cache.js";import{evaluateExpressionsRecursively as m}from"./utils.js";async function d(e,r){const{path:a,value:u,items:s}=r;if(!a||typeof a!="string")throw new n(r,'unshift action requires "path" parameter',o.ACTION_MISSING_PARAM,{metadata:{param:"path"}});const t=e._get(a);if(!Array.isArray(t))throw new n(r,`Path "${a}" does not point to an array`,o.ACTION_INVALID_PARAM,{metadata:{param:"path",path:a,actualType:typeof t}});const p=s!==void 0?s:u;if(p===void 0)throw new n(r,'unshift action requires "value" or "items" parameter',o.ACTION_MISSING_PARAM,{metadata:{param:"value|items"}});const i=m(p,e);Array.isArray(i)?t.unshift(...i):t.unshift(i),f(a,e),f(`${a}.*`,e)}export{d as handleUnshift};
@@ -1,33 +1 @@
1
- /**
2
- * 数组指令工具函数
3
- */
4
- import { evaluate } from '../../../expression/evaluate.js';
5
- /**
6
- * 递归求值对象/数组中的表达式
7
- * 支持在对象属性和数组元素中使用 {{ expression }} 格式
8
- */
9
- export function evaluateExpressionsRecursively(value, ctx) {
10
- // 字符串:检查是否为表达式
11
- if (typeof value === 'string') {
12
- if (value.startsWith('{{') && value.endsWith('}}')) {
13
- const expr = value.slice(2, -2).trim();
14
- return evaluate(expr, ctx);
15
- }
16
- return value;
17
- }
18
- // 数组:递归处理每个元素
19
- if (Array.isArray(value)) {
20
- return value.map(item => evaluateExpressionsRecursively(item, ctx));
21
- }
22
- // 对象:递归处理每个属性值
23
- if (value && typeof value === 'object') {
24
- const result = {};
25
- for (const [key, val] of Object.entries(value)) {
26
- result[key] = evaluateExpressionsRecursively(val, ctx);
27
- }
28
- return result;
29
- }
30
- // 其他类型:直接返回
31
- return value;
32
- }
33
- //# sourceMappingURL=utils.js.map
1
+ import{evaluate as o}from"../../../expression/evaluate.js";function s(r,i){if(typeof r=="string"){if(r.startsWith("{{")&&r.endsWith("}}")){const t=r.slice(2,-2).trim();return o(t,i)}return r}if(Array.isArray(r))return r.map(t=>s(t,i));if(r&&typeof r=="object"){const t={};for(const[e,n]of Object.entries(r))t[e]=s(n,i);return t}return r}export{s as evaluateExpressionsRecursively};
@@ -1,40 +1 @@
1
- /**
2
- * batch 动作处理器
3
- *
4
- * 功能:批量执行动作(保证原子性)
5
- * 示例:{ "type": "batch", "actions": [...] }
6
- */
7
- import { ActionError, BatchError, ErrorCodes } from '../../errors.js';
8
- import { execute } from '../executor.js';
9
- /**
10
- * 处理 batch 动作
11
- */
12
- export async function handleBatch(ctx, action) {
13
- const { actions } = action;
14
- if (!actions || !Array.isArray(actions)) {
15
- throw new ActionError(action, 'batch action requires "actions" parameter (array)', ErrorCodes.ACTION_MISSING_PARAM, { metadata: { param: 'actions' } });
16
- }
17
- const errors = [];
18
- // 批量执行,收集错误
19
- for (const act of actions) {
20
- try {
21
- await execute([act], ctx);
22
- }
23
- catch (error) {
24
- errors.push({
25
- action: act,
26
- error: error instanceof Error ? error : new Error(String(error))
27
- });
28
- }
29
- }
30
- // 如果有错误,抛出 BatchError
31
- if (errors.length > 0) {
32
- throw new BatchError(errors, `${errors.length} actions failed in batch`, {
33
- metadata: {
34
- failedCount: errors.length,
35
- totalCount: actions.length
36
- }
37
- });
38
- }
39
- }
40
- //# sourceMappingURL=batch.js.map
1
+ import{ActionError as c,BatchError as i,ErrorCodes as s}from"../../errors.js";import{execute as h}from"../executor.js";async function m(e,o){const{actions:t}=o;if(!t||!Array.isArray(t))throw new c(o,'batch action requires "actions" parameter (array)',s.ACTION_MISSING_PARAM,{metadata:{param:"actions"}});const r=[];for(const n of t)try{await h([n],e)}catch(a){r.push({action:n,error:a instanceof Error?a:new Error(String(a))})}if(r.length>0)throw new i(r,`${r.length} actions failed in batch`,{metadata:{failedCount:r.length,totalCount:t.length}})}export{m as handleBatch};
@@ -1,65 +1 @@
1
- /**
2
- * call 动作处理器
3
- *
4
- * 功能:调用 method(通过 $methods)
5
- * 示例:{ "type": "call", "method": "services.fetchUser", "params": {...}, "resultTo": "user" }
6
- *
7
- * 参考文档:action-reference.md - call 动作
8
- */
9
- import { ActionError, ServiceError, ErrorCodes } from '../../errors.js';
10
- import { evaluate } from '../../expression/evaluate.js';
11
- import { invalidateCache } from '../../expression/cache.js';
12
- /**
13
- * 处理 call 动作
14
- */
15
- export async function handleCall(ctx, action) {
16
- const method = action.method;
17
- const params = (action.params || {});
18
- const resultTo = action.resultTo;
19
- if (!method || typeof method !== 'string') {
20
- throw new ActionError(action, 'call action requires "method" parameter', ErrorCodes.ACTION_MISSING_PARAM, { metadata: { param: 'method' } });
21
- }
22
- // 查找方法(通过 $methods)
23
- const handler = ctx.$methods[method];
24
- if (!handler) {
25
- throw new ServiceError(method, `Method "${method}" not found in $methods`, undefined, {
26
- metadata: { method }
27
- });
28
- }
29
- // 求值参数(支持表达式)
30
- const finalParams = {};
31
- try {
32
- for (const [key, value] of Object.entries(params)) {
33
- if (typeof value === 'string' && value.startsWith('{{') && value.endsWith('}}')) {
34
- const expr = value.slice(2, -2).trim();
35
- finalParams[key] = evaluate(expr, ctx);
36
- }
37
- else {
38
- finalParams[key] = value;
39
- }
40
- }
41
- // 调用 method
42
- const result = await handler(ctx, finalParams);
43
- // 如果指定了 resultTo,保存结果到状态
44
- if (resultTo) {
45
- ctx._set(resultTo, result);
46
- invalidateCache(resultTo, ctx);
47
- }
48
- return result;
49
- }
50
- catch (error) {
51
- // 如果错误已经是 ServiceError,直接抛出
52
- if (error instanceof ServiceError) {
53
- throw error;
54
- }
55
- const errorMessage = error instanceof Error ? error.message : String(error);
56
- const originalError = error instanceof Error ? error : undefined;
57
- throw new ServiceError(method, `Service call failed: ${errorMessage}`, originalError, {
58
- metadata: {
59
- method,
60
- params: finalParams
61
- }
62
- });
63
- }
64
- }
65
- //# sourceMappingURL=call.js.map
1
+ import{ActionError as l,ServiceError as m,ErrorCodes as h}from"../../errors.js";import{evaluate as p}from"../../expression/evaluate.js";import{invalidateCache as u}from"../../expression/cache.js";async function v(o,a){const e=a.method,f=a.params||{},i=a.resultTo;if(!e||typeof e!="string")throw new l(a,'call action requires "method" parameter',h.ACTION_MISSING_PARAM,{metadata:{param:"method"}});const d=o.$methods[e];if(!d)throw new m(e,`Method "${e}" not found in $methods`,void 0,{metadata:{method:e}});const n={};try{for(const[s,t]of Object.entries(f))if(typeof t=="string"&&t.startsWith("{{")&&t.endsWith("}}")){const c=t.slice(2,-2).trim();n[s]=p(c,o)}else n[s]=t;const r=await d(o,n);return i&&(o._set(i,r),u(i,o)),r}catch(r){if(r instanceof m)throw r;const s=r instanceof Error?r.message:String(r),t=r instanceof Error?r:void 0;throw new m(e,`Service call failed: ${s}`,t,{metadata:{method:e,params:n}})}}export{v as handleCall};
@@ -1,26 +1 @@
1
- /**
2
- * emit 动作处理器
3
- *
4
- * 功能:触发事件
5
- * 示例:{ "type": "emit", "event": "submit", "data": { "userId": 123 } }
6
- */
7
- import { ActionError, ErrorCodes } from '../../errors.js';
8
- import { evaluate } from '../../expression/evaluate.js';
9
- /**
10
- * 处理 emit 动作
11
- */
12
- export async function handleEmit(ctx, action) {
13
- const { event, data } = action;
14
- if (!event || typeof event !== 'string') {
15
- throw new ActionError(action, 'emit action requires "event" parameter', ErrorCodes.ACTION_MISSING_PARAM, { metadata: { param: 'event' } });
16
- }
17
- // 求值 data(支持表达式)
18
- let finalData = data;
19
- if (typeof data === 'string' && data.startsWith('{{') && data.endsWith('}}')) {
20
- const expr = data.slice(2, -2).trim();
21
- finalData = evaluate(expr, ctx);
22
- }
23
- // 触发事件
24
- ctx.$emit(event, finalData);
25
- }
26
- //# sourceMappingURL=emit.js.map
1
+ import{ActionError as o,ErrorCodes as m}from"../../errors.js";import{evaluate as s}from"../../expression/evaluate.js";async function c(r,a){const{event:e,data:t}=a;if(!e||typeof e!="string")throw new o(a,'emit action requires "event" parameter',m.ACTION_MISSING_PARAM,{metadata:{param:"event"}});let i=t;if(typeof t=="string"&&t.startsWith("{{")&&t.endsWith("}}")){const n=t.slice(2,-2).trim();i=s(n,r)}r.$emit(e,i)}export{c as handleEmit};
@@ -1,35 +1 @@
1
- /**
2
- * if 动作处理器
3
- *
4
- * 功能:条件分支
5
- * 示例:{ "type": "if", "cond": "user.age > 18", "then": [...], "else": [...] }
6
- * 示例:{ "type": "if", "cond": "{{ counter < 10 }}", "then": [...], "else": [...] }
7
- */
8
- import { ActionError, ErrorCodes } from '../../errors.js';
9
- import { evaluate, extractExpression } from '../../expression/index.js';
10
- import { execute } from '../executor.js';
11
- /**
12
- * 处理 if 动作
13
- */
14
- export async function handleIf(ctx, action) {
15
- const { cond, then, else: elseBranch } = action;
16
- if (!cond || typeof cond !== 'string') {
17
- throw new ActionError(action, 'if action requires "cond" parameter', ErrorCodes.ACTION_MISSING_PARAM, { metadata: { param: 'cond' } });
18
- }
19
- // 提取表达式(支持 {{ }} 格式)
20
- const condExpr = extractExpression(cond);
21
- // 求值条件表达式
22
- const condition = evaluate(condExpr, ctx);
23
- // 执行对应的分支
24
- if (condition) {
25
- if (then && Array.isArray(then)) {
26
- await execute(then, ctx);
27
- }
28
- }
29
- else {
30
- if (elseBranch && Array.isArray(elseBranch)) {
31
- await execute(elseBranch, ctx);
32
- }
33
- }
34
- }
35
- //# sourceMappingURL=if.js.map
1
+ import{ActionError as s,ErrorCodes as c}from"../../errors.js";import{evaluate as f,extractExpression as d}from"../../expression/index.js";import{execute as i}from"../executor.js";async function l(r,a){const{cond:o,then:e,else:t}=a;if(!o||typeof o!="string")throw new s(a,'if action requires "cond" parameter',c.ACTION_MISSING_PARAM,{metadata:{param:"cond"}});const n=d(o);f(n,r)?e&&Array.isArray(e)&&await i(e,r):t&&Array.isArray(t)&&await i(t,r)}export{l as handleIf};
@@ -1,55 +1 @@
1
- /**
2
- * 内置动作处理器
3
- *
4
- * 所有内置动作统一注册到 ctx.$methods
5
- */
6
- import { handleSet } from './set.js';
7
- import { handleEmit } from './emit.js';
8
- import { handleIf } from './if.js';
9
- import { handleLoop } from './loop.js';
10
- import { handleCall } from './call.js';
11
- import { handleBatch } from './batch.js';
12
- import { handleNavigate } from './navigate.js';
13
- import { handleLog } from './log.js';
14
- import { handlePush } from './array/push.js';
15
- import { handlePop } from './array/pop.js';
16
- import { handleShift } from './array/shift.js';
17
- import { handleUnshift } from './array/unshift.js';
18
- import { handleSplice } from './array/splice.js';
19
- /**
20
- * 内置动作处理器映射
21
- */
22
- const BUILTIN_METHODS = {
23
- // 原子动作
24
- 'set': handleSet,
25
- 'emit': handleEmit,
26
- 'navigate': handleNavigate,
27
- 'log': handleLog,
28
- // 控制流动作
29
- 'if': handleIf,
30
- 'loop': handleLoop,
31
- // 复合动作
32
- 'call': handleCall,
33
- 'batch': handleBatch,
34
- // 数组操作动作
35
- 'push': handlePush,
36
- 'pop': handlePop,
37
- 'shift': handleShift,
38
- 'unshift': handleUnshift,
39
- 'splice': handleSplice,
40
- };
41
- /**
42
- * 注册所有内置动作到 $methods
43
- *
44
- * 注意:此函数通过向现有 $methods 对象添加属性来注册方法,
45
- * 而不是整体覆盖 $methods,以确保在 Proxy 保护下也能正常工作。
46
- */
47
- export function registerBuiltinMethods(ctx) {
48
- // 向现有 $methods 对象添加内置方法,不覆盖已有的同名方法
49
- for (const [name, handler] of Object.entries(BUILTIN_METHODS)) {
50
- if (!(name in ctx.$methods)) {
51
- ctx.$methods[name] = handler;
52
- }
53
- }
54
- }
55
- //# sourceMappingURL=index.js.map
1
+ import{handleSet as e}from"./set.js";import{handleEmit as i}from"./emit.js";import{handleIf as m}from"./if.js";import{handleLoop as h}from"./loop.js";import{handleCall as n}from"./call.js";import{handleBatch as a}from"./batch.js";import{handleNavigate as f}from"./navigate.js";import{handleLog as l}from"./log.js";import{handlePush as p}from"./array/push.js";import{handlePop as d}from"./array/pop.js";import{handleShift as s}from"./array/shift.js";import{handleUnshift as c}from"./array/unshift.js";import{handleSplice as g}from"./array/splice.js";const u={set:e,emit:i,navigate:f,log:l,if:m,loop:h,call:n,batch:a,push:p,pop:d,shift:s,unshift:c,splice:g};function $(o){for(const[t,r]of Object.entries(u))t in o.$methods||(o.$methods[t]=r)}export{$ as registerBuiltinMethods};
@@ -1,41 +1 @@
1
- /**
2
- * log 动作处理器
3
- *
4
- * 功能:调试输出
5
- * 示例:{ "type": "log", "level": "info", "message": "User logged in" }
6
- */
7
- import { ActionError, ErrorCodes } from '../../errors.js';
8
- import { evaluate } from '../../expression/evaluate.js';
9
- /**
10
- * 处理 log 动作
11
- */
12
- export async function handleLog(ctx, action) {
13
- const { level = 'info', message } = action;
14
- if (!message) {
15
- throw new ActionError(action, 'log action requires "message" parameter', ErrorCodes.ACTION_MISSING_PARAM, { metadata: { param: 'message' } });
16
- }
17
- // 求值 message(支持表达式)
18
- let finalMessage = message;
19
- if (typeof message === 'string' && message.startsWith('{{') && message.endsWith('}}')) {
20
- const expr = message.slice(2, -2).trim();
21
- finalMessage = evaluate(expr, ctx);
22
- }
23
- // 输出日志(将 finalMessage 转换为字符串)
24
- const logLevel = String(level).toLowerCase();
25
- const messageStr = String(finalMessage);
26
- if (typeof console !== 'undefined') {
27
- switch (logLevel) {
28
- case 'error':
29
- console.error('[Vario]', messageStr);
30
- break;
31
- case 'warn':
32
- console.warn('[Vario]', messageStr);
33
- break;
34
- case 'info':
35
- default:
36
- console.log('[Vario]', messageStr);
37
- break;
38
- }
39
- }
40
- }
41
- //# sourceMappingURL=log.js.map
1
+ import{ActionError as c,ErrorCodes as l}from"../../errors.js";import{evaluate as f}from"../../expression/evaluate.js";async function p(s,o){const{level:t="info",message:e}=o;if(!e)throw new c(o,'log action requires "message" parameter',l.ACTION_MISSING_PARAM,{metadata:{param:"message"}});let a=e;if(typeof e=="string"&&e.startsWith("{{")&&e.endsWith("}}")){const i=e.slice(2,-2).trim();a=f(i,s)}const n=String(t).toLowerCase(),r=String(a);if(typeof console<"u")switch(n){case"error":console.error("[Vario]",r);break;case"warn":console.warn("[Vario]",r);break;case"info":default:console.log("[Vario]",r);break}}export{p as handleLog};
@@ -1,71 +1 @@
1
- /**
2
- * loop 动作处理器
3
- *
4
- * 功能:循环执行
5
- * 示例:{ "type": "loop", "var": "item", "in": "items", "body": [...] }
6
- */
7
- import { ActionError, ErrorCodes } from '../../errors.js';
8
- import { evaluate } from '../../expression/evaluate.js';
9
- import { invalidateCache } from '../../expression/cache.js';
10
- import { execute } from '../executor.js';
11
- import { createLoopContext, releaseLoopContext } from '../../runtime/loop-context-pool.js';
12
- /**
13
- * 处理 loop 动作
14
- */
15
- export async function handleLoop(ctx, action) {
16
- const { var: varName, in: inExpr, body } = action;
17
- if (!varName || typeof varName !== 'string') {
18
- throw new ActionError(action, 'loop action requires "var" parameter', ErrorCodes.ACTION_MISSING_PARAM, { metadata: { param: 'var' } });
19
- }
20
- if (!inExpr || typeof inExpr !== 'string') {
21
- throw new ActionError(action, 'loop action requires "in" parameter', ErrorCodes.ACTION_MISSING_PARAM, { metadata: { param: 'in' } });
22
- }
23
- if (!body || !Array.isArray(body)) {
24
- throw new ActionError(action, 'loop action requires "body" parameter (array of actions)', ErrorCodes.ACTION_MISSING_PARAM, { metadata: { param: 'body' } });
25
- }
26
- // 求值 in 表达式,获取要遍历的数组或对象
27
- const iterable = evaluate(inExpr, ctx);
28
- if (iterable == null) {
29
- return;
30
- }
31
- // 遍历数组
32
- if (Array.isArray(iterable)) {
33
- for (let i = 0; i < iterable.length; i++) {
34
- // 使用对象池创建循环上下文
35
- const loopCtx = createLoopContext(ctx, iterable[i], i);
36
- loopCtx[varName] = iterable[i];
37
- try {
38
- // 触发缓存失效,确保表达式重新求值
39
- invalidateCache(varName, loopCtx);
40
- await execute(body, loopCtx);
41
- }
42
- finally {
43
- // 释放循环上下文回对象池
44
- releaseLoopContext(loopCtx);
45
- }
46
- }
47
- }
48
- // 遍历对象
49
- else if (typeof iterable === 'object' && iterable !== null) {
50
- const entries = Object.entries(iterable);
51
- for (let i = 0; i < entries.length; i++) {
52
- const [, value] = entries[i];
53
- // 使用对象池创建循环上下文
54
- const loopCtx = createLoopContext(ctx, value, i);
55
- loopCtx[varName] = value;
56
- try {
57
- // 触发缓存失效,确保表达式重新求值
58
- invalidateCache(varName, loopCtx);
59
- await execute(body, loopCtx);
60
- }
61
- finally {
62
- // 释放循环上下文回对象池
63
- releaseLoopContext(loopCtx);
64
- }
65
- }
66
- }
67
- else {
68
- throw new ActionError(action, `loop "in" expression must evaluate to an array or object, got ${typeof iterable}`, ErrorCodes.ACTION_INVALID_PARAM, { metadata: { param: 'in', actualType: typeof iterable } });
69
- }
70
- }
71
- //# sourceMappingURL=loop.js.map
1
+ import{ActionError as p,ErrorCodes as l}from"../../errors.js";import{evaluate as I}from"../../expression/evaluate.js";import{invalidateCache as y}from"../../expression/cache.js";import{execute as A}from"../executor.js";import{createLoopContext as c,releaseLoopContext as u}from"../../runtime/loop-context-pool.js";async function v(s,a){const{var:o,in:m,body:i}=a;if(!o||typeof o!="string")throw new p(a,'loop action requires "var" parameter',l.ACTION_MISSING_PARAM,{metadata:{param:"var"}});if(!m||typeof m!="string")throw new p(a,'loop action requires "in" parameter',l.ACTION_MISSING_PARAM,{metadata:{param:"in"}});if(!i||!Array.isArray(i))throw new p(a,'loop action requires "body" parameter (array of actions)',l.ACTION_MISSING_PARAM,{metadata:{param:"body"}});const r=I(m,s);if(r!=null)if(Array.isArray(r))for(let t=0;t<r.length;t++){const e=c(s,r[t],t);e[o]=r[t];try{y(o,e),await A(i,e)}finally{u(e)}}else if(typeof r=="object"&&r!==null){const t=Object.entries(r);for(let e=0;e<t.length;e++){const[,f]=t[e],n=c(s,f,e);n[o]=f;try{y(o,n),await A(i,n)}finally{u(n)}}}else throw new p(a,`loop "in" expression must evaluate to an array or object, got ${typeof r}`,l.ACTION_INVALID_PARAM,{metadata:{param:"in",actualType:typeof r}})}export{v as handleLoop};
@@ -1,43 +1 @@
1
- /**
2
- * navigate 动作处理器
3
- *
4
- * 功能:路由导航
5
- * 示例:{ "type": "navigate", "to": "/users/123" }
6
- */
7
- import { ActionError, ErrorCodes } from '../../errors.js';
8
- import { evaluate } from '../../expression/evaluate.js';
9
- /**
10
- * 处理 navigate 动作
11
- */
12
- export async function handleNavigate(ctx, action) {
13
- const { to } = action;
14
- if (!to || typeof to !== 'string') {
15
- throw new ActionError(action, 'navigate action requires "to" parameter', ErrorCodes.ACTION_MISSING_PARAM, { metadata: { param: 'to' } });
16
- }
17
- // 求值 to(支持表达式)
18
- let finalTo = to;
19
- if (to.startsWith('{{') && to.endsWith('}}')) {
20
- const expr = to.slice(2, -2).trim();
21
- const result = evaluate(expr, ctx);
22
- if (typeof result !== 'string') {
23
- throw new ActionError(action, `navigate "to" expression must evaluate to a string, got ${typeof result}`, ErrorCodes.ACTION_INVALID_PARAM, { metadata: { param: 'to', actualType: typeof result } });
24
- }
25
- finalTo = result;
26
- }
27
- // 调用路由导航方法(如果已注册)
28
- const navigateHandler = ctx.$methods['navigate'] || ctx.$methods['$navigate'];
29
- if (navigateHandler) {
30
- await navigateHandler(ctx, { to: finalTo });
31
- }
32
- else {
33
- // 如果没有注册导航方法,使用默认行为(浏览器导航)
34
- // 使用类型安全的 window 访问
35
- if (typeof window !== 'undefined' && window.location) {
36
- window.location.href = finalTo;
37
- }
38
- else {
39
- throw new ActionError(action, 'navigate method not registered and window.location is not available', ErrorCodes.ACTION_EXECUTION_ERROR, { metadata: { reason: 'navigate_not_available' } });
40
- }
41
- }
42
- }
43
- //# sourceMappingURL=navigate.js.map
1
+ import{ActionError as n,ErrorCodes as r}from"../../errors.js";import{evaluate as l}from"../../expression/evaluate.js";async function w(e,a){const{to:t}=a;if(!t||typeof t!="string")throw new n(a,'navigate action requires "to" parameter',r.ACTION_MISSING_PARAM,{metadata:{param:"to"}});let i=t;if(t.startsWith("{{")&&t.endsWith("}}")){const d=t.slice(2,-2).trim(),o=l(d,e);if(typeof o!="string")throw new n(a,`navigate "to" expression must evaluate to a string, got ${typeof o}`,r.ACTION_INVALID_PARAM,{metadata:{param:"to",actualType:typeof o}});i=o}const s=e.$methods.navigate||e.$methods.$navigate;if(s)await s(e,{to:i});else if(typeof window<"u"&&window.location)window.location.href=i;else throw new n(a,"navigate method not registered and window.location is not available",r.ACTION_EXECUTION_ERROR,{metadata:{reason:"navigate_not_available"}})}export{w as handleNavigate};
@@ -1,30 +1 @@
1
- /**
2
- * set 动作处理器
3
- *
4
- * 功能:修改状态
5
- * 示例:{ "type": "set", "path": "user.name", "value": "张三" }
6
- *
7
- * 注意:缓存失效通过 RuntimeContext 的 onStateChange 钩子处理
8
- * 框架集成层应在创建上下文时注册该钩子
9
- */
10
- import { ActionError, ErrorCodes } from '../../errors.js';
11
- import { evaluate } from '../../expression/evaluate.js';
12
- /**
13
- * 处理 set 动作
14
- */
15
- export async function handleSet(ctx, action) {
16
- const { path, value } = action;
17
- if (!path || typeof path !== 'string') {
18
- throw new ActionError(action, 'set action requires "path" parameter', ErrorCodes.ACTION_MISSING_PARAM, { metadata: { param: 'path' } });
19
- }
20
- // 求值 value(支持表达式)
21
- let finalValue = value;
22
- if (typeof value === 'string' && value.startsWith('{{') && value.endsWith('}}')) {
23
- // 表达式插值:{{ user.age + 1 }}
24
- const expr = value.slice(2, -2).trim();
25
- finalValue = evaluate(expr, ctx);
26
- }
27
- // 设置状态(缓存失效通过 onStateChange 钩子自动处理)
28
- ctx._set(path, finalValue);
29
- }
30
- //# sourceMappingURL=set.js.map
1
+ import{ActionError as s,ErrorCodes as n}from"../../errors.js";import{evaluate as p}from"../../expression/evaluate.js";async function h(r,a){const{path:e,value:t}=a;if(!e||typeof e!="string")throw new s(a,'set action requires "path" parameter',n.ACTION_MISSING_PARAM,{metadata:{param:"path"}});let o=t;if(typeof t=="string"&&t.startsWith("{{")&&t.endsWith("}}")){const i=t.slice(2,-2).trim();o=p(i,r)}r._set(e,o)}export{h as handleSet};
package/dist/vm/index.js CHANGED
@@ -1,7 +1 @@
1
- /**
2
- * VM 模块导出
3
- */
4
- export { execute } from './executor.js';
5
- export { registerBuiltinMethods } from './handlers/index.js';
6
- export * from './errors.js';
7
- //# sourceMappingURL=index.js.map
1
+ import{execute as o}from"./executor.js";import{registerBuiltinMethods as x}from"./handlers/index.js";export*from"./errors.js";export{o as execute,x as registerBuiltinMethods};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@variojs/core",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Vario Core Runtime - Instruction VM, Expression System, Runtime Context",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "scripts": {
16
16
  "build": "tsc",
17
- "postbuild": "tsc-alias",
17
+ "postbuild": "tsc-alias && node ../../scripts/minify.js",
18
18
  "dev": "tsc --watch",
19
19
  "test": "vitest run",
20
20
  "test:watch": "vitest",