node-riner 2.0.1 → 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.
Files changed (2) hide show
  1. package/index.ts +39 -4
  2. 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 (!this.rinerMoves.includes(src)) this.rinerMoves.push(src)
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 })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-riner",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "main": "index.ts",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",