node-riner 2.0.2 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.ts +39 -4
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -21,6 +21,9 @@ export default class Ride {
|
|
|
21
21
|
private rinerState: Record<string, any>
|
|
22
22
|
private rinerMoves: string[]
|
|
23
23
|
|
|
24
|
+
// Re 用の登録されたキー一覧(動的バインド)
|
|
25
|
+
private rinerRebinds: Set<string>
|
|
26
|
+
|
|
24
27
|
constructor(name: string) {
|
|
25
28
|
this.F = ""
|
|
26
29
|
this.parsedJson = {}
|
|
@@ -31,6 +34,29 @@ export default class Ride {
|
|
|
31
34
|
this.defaultContext = {}
|
|
32
35
|
this.rinerState = {}
|
|
33
36
|
this.rinerMoves = []
|
|
37
|
+
this.rinerRebinds = new Set()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Re の鍵群を登録する。要素は
|
|
42
|
+
* - 文字列: 名前のみ登録(初期値 null)
|
|
43
|
+
* - [name, initial] の配列: 名前と初期値を登録
|
|
44
|
+
*/
|
|
45
|
+
private registerRebinds(rebind: any[]): boolean {
|
|
46
|
+
if (!Array.isArray(rebind)) return false
|
|
47
|
+
for (const item of rebind) {
|
|
48
|
+
if (Array.isArray(item) && item.length >= 1) {
|
|
49
|
+
const name = String(item[0])
|
|
50
|
+
const init = item.length >= 2 ? item[1] : null
|
|
51
|
+
if (!this.rinerRebinds.has(name)) this.rinerRebinds.add(name)
|
|
52
|
+
if (!(name in this.rinerState)) this.rinerState[name] = init
|
|
53
|
+
} else {
|
|
54
|
+
const name = String(item)
|
|
55
|
+
if (!this.rinerRebinds.has(name)) this.rinerRebinds.add(name)
|
|
56
|
+
if (!(name in this.rinerState)) this.rinerState[name] = null
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return true
|
|
34
60
|
}
|
|
35
61
|
|
|
36
62
|
/**
|
|
@@ -72,7 +98,7 @@ export default class Ride {
|
|
|
72
98
|
/**
|
|
73
99
|
* 値を再帰的に HTML に変換するユーティリティ
|
|
74
100
|
* - ctx を渡すと { ... } 内のコードをそのコンテキストで評価する
|
|
75
|
-
* - riner.out / riner.move / riner.state を提供
|
|
101
|
+
* - riner.out / riner.move / riner.state / riner.Re を提供
|
|
76
102
|
*/
|
|
77
103
|
private renderValue(value: any, ctx: any = {}): string {
|
|
78
104
|
if (value === null || value === undefined) return ''
|
|
@@ -94,6 +120,8 @@ export default class Ride {
|
|
|
94
120
|
// sandbox を組み立て:ctx をコピー、riner、そしてトップレベルに rinerState を展開
|
|
95
121
|
const sandbox: Record<string, any> = Object.assign({}, ctx)
|
|
96
122
|
|
|
123
|
+
const self = this
|
|
124
|
+
|
|
97
125
|
// riner オブジェクト(host 側のメソッドはクロスコンテキストで呼ばれる)
|
|
98
126
|
sandbox.riner = {
|
|
99
127
|
// 出力を収集するために riner.out を提供
|
|
@@ -103,12 +131,21 @@ export default class Ride {
|
|
|
103
131
|
try {
|
|
104
132
|
const src = fn.toString()
|
|
105
133
|
// 重複を避けるため同一ソースは再登録しない
|
|
106
|
-
if (!
|
|
134
|
+
if (!self.rinerMoves.includes(src)) self.rinerMoves.push(src)
|
|
107
135
|
return true
|
|
108
136
|
} catch (e) {
|
|
109
137
|
return false
|
|
110
138
|
}
|
|
111
139
|
},
|
|
140
|
+
// Re: 動的バインドを登録する
|
|
141
|
+
// 使い方例: riner.Re(['count']) または riner.Re([['count', 0]])
|
|
142
|
+
Re: (rebind: any[]) => {
|
|
143
|
+
try {
|
|
144
|
+
return self.registerRebinds(rebind)
|
|
145
|
+
} catch (e) {
|
|
146
|
+
return false
|
|
147
|
+
}
|
|
148
|
+
},
|
|
112
149
|
// 直接 state にアクセスできるように参照を渡す
|
|
113
150
|
state: this.rinerState
|
|
114
151
|
}
|
|
@@ -126,8 +163,6 @@ export default class Ride {
|
|
|
126
163
|
}
|
|
127
164
|
|
|
128
165
|
// 実行
|
|
129
|
-
console.log(sandbox)
|
|
130
|
-
console.log(code)
|
|
131
166
|
let res: any
|
|
132
167
|
try {
|
|
133
168
|
res = runInNewContext(code, sandbox, { timeout: 2000 })
|