@dongmingzhixiu/vuexir 0.3.5 → 0.3.7

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.
package/dist/bundle.js CHANGED
@@ -13,7 +13,7 @@ import { join } from 'node:path';
13
13
  import { buildSync } from 'esbuild';
14
14
  import { mkdtempSync, writeFileSync } from 'node:fs';
15
15
  import { tmpdir } from 'node:os';
16
- import { DEXIE_SHIM_SOURCE } from './shims.js';
16
+ import { DEXIE_SHIM_SOURCE, PINIA_SHIM_SOURCE, VUE_SHIM_SOURCE } from './shims.js';
17
17
  /** 打包 src/utils 下可独立运行的 util(`@/types` 等纯类型导入会被 esbuild 擦除) */
18
18
  export function bundleProjectUtils(projectRoot) {
19
19
  const utilsDir = join(projectRoot, 'src', 'utils');
@@ -23,37 +23,51 @@ export function bundleProjectUtils(projectRoot) {
23
23
  const shimDir = mkdtempSync(join(tmpdir(), 'vrn-shim-'));
24
24
  const dexieShim = join(shimDir, 'dexie-shim.js');
25
25
  writeFileSync(dexieShim, DEXIE_SHIM_SOURCE);
26
+ const vueShim = join(shimDir, 'vue-shim.js');
27
+ writeFileSync(vueShim, VUE_SHIM_SOURCE);
28
+ const piniaShim = join(shimDir, 'pinia-shim.js');
29
+ writeFileSync(piniaShim, PINIA_SHIM_SOURCE);
26
30
  const included = [];
27
31
  const skipped = [];
28
32
  const chunks = [];
29
- for (const file of readdirSync(utilsDir)) {
30
- if (!/\.(ts|js|mts)$/.test(file) || file.endsWith('.d.ts'))
31
- continue;
32
- try {
33
- const out = buildSync({
34
- entryPoints: [join(utilsDir, file)],
35
- bundle: true,
36
- write: false,
37
- format: 'iife',
38
- // 每个文件一个独立命名空间,避免后一个 IIFE 覆盖前一个的导出
39
- globalName: `__vrnUtils_${included.length}`,
40
- platform: 'neutral',
41
- target: 'es2019',
42
- // 纯类型导入会被擦除;若确实依赖运行期外部包(dexie 等)则整包失败 → 跳过该文件
43
- external: [],
44
- logLevel: 'silent',
45
- alias: { '@': join(projectRoot, 'src'), dexie: dexieShim },
46
- });
47
- const code = out.outputFiles?.[0]?.text ?? '';
48
- if (code) {
49
- // 导出提升为全局:模板表达式里是裸调用(countChars(...)),必须能在全局找到
50
- chunks.push(code +
51
- `\n;(function(){var m=__vrnUtils_${included.length};if(!m)return;for(var k in m){try{if(typeof globalThis[k]==='undefined')globalThis[k]=m[k];}catch(e){}}})();`);
52
- included.push(file);
33
+ // stores 也一起打:页面/工具里的 useXxxStore 需要真实实现(pinia shim 顶上)
34
+ const storesDir = join(projectRoot, 'src', 'stores');
35
+ const dirs = [utilsDir, storesDir].filter((d) => existsSync(d));
36
+ for (const dir of dirs) {
37
+ for (const file of readdirSync(dir)) {
38
+ if (!/\.(ts|js|mts)$/.test(file) || file.endsWith('.d.ts'))
39
+ continue;
40
+ try {
41
+ const out = buildSync({
42
+ entryPoints: [join(dir, file)],
43
+ bundle: true,
44
+ write: false,
45
+ format: 'iife',
46
+ // 每个文件一个独立命名空间,避免后一个 IIFE 覆盖前一个的导出
47
+ globalName: `__vrnUtils_${included.length}`,
48
+ platform: 'neutral',
49
+ target: 'es2019',
50
+ // 纯类型导入会被擦除;若确实依赖运行期外部包(dexie 等)则整包失败 → 跳过该文件
51
+ external: [],
52
+ logLevel: 'silent',
53
+ alias: {
54
+ '@': join(projectRoot, 'src'),
55
+ dexie: dexieShim,
56
+ vue: vueShim,
57
+ pinia: piniaShim,
58
+ },
59
+ });
60
+ const code = out.outputFiles?.[0]?.text ?? '';
61
+ if (code) {
62
+ // 导出提升为全局:模板表达式里是裸调用(countChars(...)),必须能在全局找到
63
+ chunks.push(code +
64
+ `\n;(function(){var m=__vrnUtils_${included.length};if(!m)return;for(var k in m){try{if(typeof globalThis[k]==='undefined')globalThis[k]=m[k];}catch(e){}}})();`);
65
+ included.push(file);
66
+ }
67
+ }
68
+ catch (e) {
69
+ skipped.push({ file, reason: e.message.split('\n')[0]?.slice(0, 120) ?? '打包失败' });
53
70
  }
54
- }
55
- catch (e) {
56
- skipped.push({ file, reason: e.message.split('\n')[0]?.slice(0, 120) ?? '打包失败' });
57
71
  }
58
72
  }
59
73
  return { code: chunks.join('\n'), included, skipped };
package/dist/shims.d.ts CHANGED
@@ -7,3 +7,19 @@
7
7
  * db.version(n).stores({...}) / table.get / put / bulkPut / toArray / delete / clear / count
8
8
  */
9
9
  export declare const DEXIE_SHIM_SOURCE = "\nfunction __vrnDbKey(db, table) { return \"vrn.db:\" + db + \":\" + table; }\n\nclass Table {\n constructor(dbName, name) { this.dbName = dbName; this.name = name; }\n _read() {\n try {\n var raw = localStorage.getItem(__vrnDbKey(this.dbName, this.name));\n return raw ? JSON.parse(raw) : [];\n } catch (e) { return []; }\n }\n _write(rows) {\n try { localStorage.setItem(__vrnDbKey(this.dbName, this.name), JSON.stringify(rows)); } catch (e) {}\n }\n async toArray() { return this._read(); }\n async count() { return this._read().length; }\n async get(key) {\n var keyName = this.keyPath || \"id\";\n return this._read().find(function (r) { return r && r[keyName] === key; });\n }\n async put(row) {\n var keyName = this.keyPath || \"id\";\n var rows = this._read();\n var i = rows.findIndex(function (r) { return r && r[keyName] === row[keyName]; });\n if (i >= 0) rows[i] = row; else rows.push(row);\n this._write(rows);\n return row[keyName];\n }\n async bulkPut(list) {\n var self = this;\n var rows = self._read();\n var keyName = self.keyPath || \"id\";\n (list || []).forEach(function (row) {\n var i = rows.findIndex(function (r) { return r && r[keyName] === row[keyName]; });\n if (i >= 0) rows[i] = row; else rows.push(row);\n });\n self._write(rows);\n return (list || []).length;\n }\n async delete(key) {\n var keyName = this.keyPath || \"id\";\n this._write(this._read().filter(function (r) { return !r || r[keyName] !== key; }));\n }\n async clear() { this._write([]); }\n where() { throw new Error(\"vrn dexie shim: where() \u6682\u4E0D\u652F\u6301\"); }\n orderBy() { throw new Error(\"vrn dexie shim: orderBy() \u6682\u4E0D\u652F\u6301\"); }\n}\n\nclass Version {\n constructor(db) { this._db = db; }\n stores(spec) {\n var db = this._db;\n Object.keys(spec || {}).forEach(function (tableName) {\n var keyPath = String(spec[tableName]).split(\",\")[0].trim();\n var t = new Table(db.name, tableName);\n t.keyPath = keyPath;\n db[tableName] = t;\n });\n return this;\n }\n}\n\nexport default class Dexie {\n constructor(name) { this.name = name; }\n version() { return new Version(this); }\n}\n";
10
+ /**
11
+ * R100 P4:`vue` 的最小 shim —— 只是为了让 stores/utils 里的 ref/computed 能在
12
+ * 原生 JS 运行时(JSC/QuickJS)里跑起来,**不是完整响应式系统**:
13
+ * · ref(x) → { value: x }(读写 .value)
14
+ * · computed(f) → 惰性求值 + 依赖收集(简单标记失效)
15
+ * · reactive(x) → 原样返回(对象引用语义)
16
+ * · onMounted → 收集回调,由宿主在页面挂载后调用
17
+ * · watch → 简单轮询式比较(同一个事件循环 tick 内触发)
18
+ */
19
+ export declare const VUE_SHIM_SOURCE = "\nvar __vrnMounted = [];\nexport function ref(v) {\n return { __vrnRef: true, value: v };\n}\nexport function shallowRef(v) { return ref(v); }\nexport function reactive(obj) { return obj; }\nexport function readonly(obj) { return obj; }\nexport function computed(fn) {\n var cache;\n var dirty = true;\n return {\n __vrnComputed: true,\n get value() {\n if (dirty) { cache = fn(); dirty = false; }\n return cache;\n },\n set value(_v) { dirty = true; },\n __invalidate: function () { dirty = true; },\n };\n}\nexport function onMounted(fn) { __vrnMounted.push(fn); }\nexport function onUnmounted() {}\nexport function onBeforeUnmount() {}\nexport function watch(source, cb) {\n var last = typeof source === \"function\" ? source() : source && source.value;\n return setInterval(function () {\n var cur = typeof source === \"function\" ? source() : source && source.value;\n if (cur !== last) { var prev = last; last = cur; cb(cur, prev); }\n }, 16);\n}\nexport function nextTick(fn) { return Promise.resolve().then(fn); }\nexport function toRefs(obj) {\n var out = {};\n Object.keys(obj || {}).forEach(function (k) { out[k] = ref(obj[k]); });\n return out;\n}\nexport function unref(v) { return v && v.__vrnRef ? v.value : v; }\nexport function isRef(v) { return !!(v && v.__vrnRef); }\nexport function __vrnRunMounted() {\n var list = __vrnMounted.slice();\n __vrnMounted.length = 0;\n list.forEach(function (fn) { try { fn(); } catch (e) {} });\n}\nexport default {\n ref: ref, shallowRef: shallowRef, reactive: reactive, readonly: readonly, computed: computed,\n onMounted: onMounted, onUnmounted: onUnmounted, onBeforeUnmount: onBeforeUnmount,\n watch: watch, nextTick: nextTick, toRefs: toRefs, unref: unref, isRef: isRef,\n};\n";
20
+ /**
21
+ * R100 P4:`pinia` 的最小 shim —— 让 `stores/*.ts` 的 defineStore 能在运行时可加载。
22
+ * 支持 options 写法(state/getters/actions)与 setup 写法(函数返回 state 与 action)。
23
+ * 单例语义:同一 id 只创建一次(与 Pinia 一致),跨页面共享。
24
+ */
25
+ export declare const PINIA_SHIM_SOURCE = "\nvar __vrnStores = {};\nfunction __vrnBind(store, obj) {\n Object.keys(obj || {}).forEach(function (k) {\n var v = obj[k];\n if (typeof v === \"function\") store[k] = v.bind(store);\n else store[k] = v;\n });\n}\nexport function defineStore(id, def) {\n return function useStore() {\n if (__vrnStores[id]) return __vrnStores[id];\n var store = {};\n if (typeof def === \"function\") {\n var ret = def();\n __vrnBind(store, ret);\n Object.keys(ret || {}).forEach(function (k) {\n if (ret[k] && ret[k].__vrnRef) store[k] = ret[k].value;\n });\n } else {\n var state = typeof def.state === \"function\" ? def.state() : def.state || {};\n Object.keys(state).forEach(function (k) { store[k] = state[k]; });\n Object.keys(def.getters || {}).forEach(function (k) {\n var g = def.getters[k];\n Object.defineProperty(store, k, {\n enumerable: true,\n get: function () { try { return g.call(store, store); } catch (e) { return undefined; } },\n });\n });\n __vrnBind(store, def.actions);\n }\n __vrnStores[id] = store;\n return store;\n };\n}\nexport function createPinia() { return {}; }\nexport function storeToRefs(store) {\n var out = {};\n Object.keys(store || {}).forEach(function (k) {\n var v = store[k];\n if (typeof v !== \"function\") out[k] = { __vrnRef: true, get value() { return store[k]; }, set value(x) { store[k] = x; } };\n });\n return out;\n}\nexport default { defineStore: defineStore, createPinia: createPinia, storeToRefs: storeToRefs };\n";
package/dist/shims.js CHANGED
@@ -73,3 +73,113 @@ export default class Dexie {
73
73
  version() { return new Version(this); }
74
74
  }
75
75
  `;
76
+ /**
77
+ * R100 P4:`vue` 的最小 shim —— 只是为了让 stores/utils 里的 ref/computed 能在
78
+ * 原生 JS 运行时(JSC/QuickJS)里跑起来,**不是完整响应式系统**:
79
+ * · ref(x) → { value: x }(读写 .value)
80
+ * · computed(f) → 惰性求值 + 依赖收集(简单标记失效)
81
+ * · reactive(x) → 原样返回(对象引用语义)
82
+ * · onMounted → 收集回调,由宿主在页面挂载后调用
83
+ * · watch → 简单轮询式比较(同一个事件循环 tick 内触发)
84
+ */
85
+ export const VUE_SHIM_SOURCE = `
86
+ var __vrnMounted = [];
87
+ export function ref(v) {
88
+ return { __vrnRef: true, value: v };
89
+ }
90
+ export function shallowRef(v) { return ref(v); }
91
+ export function reactive(obj) { return obj; }
92
+ export function readonly(obj) { return obj; }
93
+ export function computed(fn) {
94
+ var cache;
95
+ var dirty = true;
96
+ return {
97
+ __vrnComputed: true,
98
+ get value() {
99
+ if (dirty) { cache = fn(); dirty = false; }
100
+ return cache;
101
+ },
102
+ set value(_v) { dirty = true; },
103
+ __invalidate: function () { dirty = true; },
104
+ };
105
+ }
106
+ export function onMounted(fn) { __vrnMounted.push(fn); }
107
+ export function onUnmounted() {}
108
+ export function onBeforeUnmount() {}
109
+ export function watch(source, cb) {
110
+ var last = typeof source === "function" ? source() : source && source.value;
111
+ return setInterval(function () {
112
+ var cur = typeof source === "function" ? source() : source && source.value;
113
+ if (cur !== last) { var prev = last; last = cur; cb(cur, prev); }
114
+ }, 16);
115
+ }
116
+ export function nextTick(fn) { return Promise.resolve().then(fn); }
117
+ export function toRefs(obj) {
118
+ var out = {};
119
+ Object.keys(obj || {}).forEach(function (k) { out[k] = ref(obj[k]); });
120
+ return out;
121
+ }
122
+ export function unref(v) { return v && v.__vrnRef ? v.value : v; }
123
+ export function isRef(v) { return !!(v && v.__vrnRef); }
124
+ export function __vrnRunMounted() {
125
+ var list = __vrnMounted.slice();
126
+ __vrnMounted.length = 0;
127
+ list.forEach(function (fn) { try { fn(); } catch (e) {} });
128
+ }
129
+ export default {
130
+ ref: ref, shallowRef: shallowRef, reactive: reactive, readonly: readonly, computed: computed,
131
+ onMounted: onMounted, onUnmounted: onUnmounted, onBeforeUnmount: onBeforeUnmount,
132
+ watch: watch, nextTick: nextTick, toRefs: toRefs, unref: unref, isRef: isRef,
133
+ };
134
+ `;
135
+ /**
136
+ * R100 P4:`pinia` 的最小 shim —— 让 `stores/*.ts` 的 defineStore 能在运行时可加载。
137
+ * 支持 options 写法(state/getters/actions)与 setup 写法(函数返回 state 与 action)。
138
+ * 单例语义:同一 id 只创建一次(与 Pinia 一致),跨页面共享。
139
+ */
140
+ export const PINIA_SHIM_SOURCE = `
141
+ var __vrnStores = {};
142
+ function __vrnBind(store, obj) {
143
+ Object.keys(obj || {}).forEach(function (k) {
144
+ var v = obj[k];
145
+ if (typeof v === "function") store[k] = v.bind(store);
146
+ else store[k] = v;
147
+ });
148
+ }
149
+ export function defineStore(id, def) {
150
+ return function useStore() {
151
+ if (__vrnStores[id]) return __vrnStores[id];
152
+ var store = {};
153
+ if (typeof def === "function") {
154
+ var ret = def();
155
+ __vrnBind(store, ret);
156
+ Object.keys(ret || {}).forEach(function (k) {
157
+ if (ret[k] && ret[k].__vrnRef) store[k] = ret[k].value;
158
+ });
159
+ } else {
160
+ var state = typeof def.state === "function" ? def.state() : def.state || {};
161
+ Object.keys(state).forEach(function (k) { store[k] = state[k]; });
162
+ Object.keys(def.getters || {}).forEach(function (k) {
163
+ var g = def.getters[k];
164
+ Object.defineProperty(store, k, {
165
+ enumerable: true,
166
+ get: function () { try { return g.call(store, store); } catch (e) { return undefined; } },
167
+ });
168
+ });
169
+ __vrnBind(store, def.actions);
170
+ }
171
+ __vrnStores[id] = store;
172
+ return store;
173
+ };
174
+ }
175
+ export function createPinia() { return {}; }
176
+ export function storeToRefs(store) {
177
+ var out = {};
178
+ Object.keys(store || {}).forEach(function (k) {
179
+ var v = store[k];
180
+ if (typeof v !== "function") out[k] = { __vrnRef: true, get value() { return store[k]; }, set value(x) { store[k] = x; } };
181
+ });
182
+ return out;
183
+ }
184
+ export default { defineStore: defineStore, createPinia: createPinia, storeToRefs: storeToRefs };
185
+ `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dongmingzhixiu/vuexir",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
4
4
  "description": "vrn 命令行:build ios|android、preview、doctor",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -21,8 +21,8 @@
21
21
  "LICENSE"
22
22
  ],
23
23
  "dependencies": {
24
- "@dongmingzhixiu/vuexir-compiler": "^0.3.5",
25
- "@dongmingzhixiu/vuexir-templates": "^0.3.5"
24
+ "@dongmingzhixiu/vuexir-compiler": "^0.3.7",
25
+ "@dongmingzhixiu/vuexir-templates": "^0.3.7"
26
26
  },
27
27
  "engines": {
28
28
  "node": ">=18"