@makano/rew 1.1.73 → 1.1.81

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 (48) hide show
  1. package/lib/rew/cli/cli.js +189 -144
  2. package/lib/rew/cli/log.js +18 -19
  3. package/lib/rew/cli/run.js +7 -9
  4. package/lib/rew/cli/utils.js +109 -95
  5. package/lib/rew/const/config_path.js +4 -0
  6. package/lib/rew/const/default.js +21 -3
  7. package/lib/rew/const/files.js +11 -8
  8. package/lib/rew/const/opt.js +6 -6
  9. package/lib/rew/css/theme.css +1 -1
  10. package/lib/rew/functions/core.js +7 -9
  11. package/lib/rew/functions/emitter.js +2 -2
  12. package/lib/rew/functions/exec.js +19 -15
  13. package/lib/rew/functions/export.js +4 -6
  14. package/lib/rew/functions/fs.js +21 -18
  15. package/lib/rew/functions/future.js +1 -1
  16. package/lib/rew/functions/import.js +55 -25
  17. package/lib/rew/functions/map.js +2 -5
  18. package/lib/rew/functions/match.js +21 -5
  19. package/lib/rew/functions/path.js +2 -2
  20. package/lib/rew/functions/require.js +16 -13
  21. package/lib/rew/functions/stdout.js +11 -11
  22. package/lib/rew/functions/types.js +67 -42
  23. package/lib/rew/html/ui.html +5 -6
  24. package/lib/rew/html/ui.js +100 -58
  25. package/lib/rew/main.js +3 -3
  26. package/lib/rew/misc/findAppInfo.js +16 -0
  27. package/lib/rew/misc/findAppPath.js +21 -0
  28. package/lib/rew/misc/seededid.js +13 -0
  29. package/lib/rew/models/struct.js +1 -1
  30. package/lib/rew/modules/compiler.js +90 -58
  31. package/lib/rew/modules/context.js +35 -22
  32. package/lib/rew/modules/runtime.js +1 -1
  33. package/lib/rew/pkgs/conf.js +50 -33
  34. package/lib/rew/pkgs/data.js +7 -2
  35. package/lib/rew/pkgs/date.js +8 -9
  36. package/lib/rew/pkgs/env.js +3 -5
  37. package/lib/rew/pkgs/modules/data/bintree.js +1 -1
  38. package/lib/rew/pkgs/modules/data/doublylinked.js +1 -1
  39. package/lib/rew/pkgs/modules/data/linkedList.js +1 -1
  40. package/lib/rew/pkgs/modules/data/queue.js +1 -2
  41. package/lib/rew/pkgs/modules/data/stack.js +1 -1
  42. package/lib/rew/pkgs/modules/threads/worker.js +31 -21
  43. package/lib/rew/pkgs/modules/ui/classes.js +68 -61
  44. package/lib/rew/pkgs/pkgs.js +5 -6
  45. package/lib/rew/pkgs/rune.js +437 -0
  46. package/lib/rew/pkgs/threads.js +30 -22
  47. package/lib/rew/pkgs/ui.js +68 -44
  48. package/package.json +8 -2
@@ -6,122 +6,130 @@ module.exports.uiClasses = (context, options, send, recieve, hook, rmHook) => {
6
6
  const _sanitizeOptions = (options) => {
7
7
  return {
8
8
  ...options,
9
- children: options.children.map(i => i.options)
10
- }
11
- }
9
+ children: options.children.map((i) => i.options),
10
+ };
11
+ };
12
12
  const RemWidgetOptions = struct({
13
- element: 'div',
14
- class: '',
13
+ element: "div",
14
+ class: "",
15
15
  attr: {},
16
- id: '',
16
+ id: "",
17
17
  data: {
18
- text: ''
18
+ text: "",
19
19
  },
20
20
  children: [],
21
- uuid: '',
22
- parent: '!any',
23
- style: {}
21
+ uuid: "",
22
+ parent: "!any",
23
+ style: {},
24
24
  });
25
25
 
26
26
  const CreatedElements = [];
27
27
 
28
28
  class RewWidget {
29
29
  _emitter = emitter();
30
- on(event, callback){
31
- const hookID = this.uuid+'_'+generateRandomID(4);
30
+ on(event, callback) {
31
+ const hookID = this.uuid + "_" + generateRandomID(4);
32
32
  this._emitter.on(event, callback, { hookID });
33
- hook(hookID, 'event_'+event, (data) => {
34
- this.emit(event, data);
35
- }, false);
36
- send({ action: 'eventListen', data: { uuid: this.uuid, event, hookID } })
33
+ hook(
34
+ hookID,
35
+ "event_" + event,
36
+ (data) => {
37
+ this.emit(event, data);
38
+ },
39
+ false,
40
+ );
41
+ send({ action: "eventListen", data: { uuid: this.uuid, event, hookID } });
37
42
  return this;
38
43
  }
39
- off(event, callback){
44
+ off(event, callback) {
40
45
  this._emitter.off(event, callback, (e) => rmHook(e.hookID));
41
46
  return this;
42
47
  }
43
- emit(event, callback){
48
+ emit(event, callback) {
44
49
  this._emitter.emit(event, callback);
45
50
  return this;
46
51
  }
47
52
 
48
53
  options = RemWidgetOptions();
49
- constructor(options = RemWidgetOptions()){
54
+ constructor(options = RemWidgetOptions()) {
50
55
  const config = RemWidgetOptions(options);
51
56
  config.uuid = generateRandomID();
52
57
  this.options = config;
53
- this.options.children.forEach(child => child.parent = this);
58
+ this.options.children.forEach((child) => (child.parent = this));
54
59
  this.init();
55
60
  CreatedElements.push(this);
56
61
  }
57
62
 
58
- init(){
59
- send({ action: 'createElement', data: _sanitizeOptions(this.options) })
63
+ init() {
64
+ send({ action: "createElement", data: _sanitizeOptions(this.options) });
60
65
  }
61
66
 
62
67
  parent = null;
63
68
 
64
- get uuid(){
69
+ get uuid() {
65
70
  return this.options.uuid;
66
71
  }
67
72
 
68
- get id(){
73
+ get id() {
69
74
  return this.options.id;
70
75
  }
71
76
 
72
- get children(){
77
+ get children() {
73
78
  return this.options.children;
74
79
  }
75
80
 
76
- find(id, recursive = true){
77
- let childFound = this.children.find(e => e.id == id) || this.children.find(e => e.uuid == id);
78
- if(childFound) return childFound;
79
- else if(!recursive) return null;
80
- for(let child of this.children){
81
+ find(id, recursive = true) {
82
+ let childFound =
83
+ this.children.find((e) => e.id == id) ||
84
+ this.children.find((e) => e.uuid == id);
85
+ if (childFound) return childFound;
86
+ else if (!recursive) return null;
87
+ for (let child of this.children) {
81
88
  let subchild = child.find(id);
82
- if(subchild) {
89
+ if (subchild) {
83
90
  return subchild;
84
91
  }
85
92
  }
86
93
  }
87
94
 
88
- update(){
89
- send({ action: 'updateElement', data: _sanitizeOptions(this.options) });
95
+ update() {
96
+ send({ action: "updateElement", data: _sanitizeOptions(this.options) });
90
97
  return this;
91
98
  }
92
99
 
93
- text(text){
100
+ text(text) {
94
101
  this.options.data.text = text;
95
102
  return this.update();
96
103
  }
97
104
 
98
- data(key, value){
99
- if(!value) return this.options.data[key];
105
+ data(key, value) {
106
+ if (!value) return this.options.data[key];
100
107
  this.options.data[key] = value;
101
- return this.update();
108
+ return this.update();
102
109
  }
103
110
 
104
- attr(attr, reset = false){
105
- if(reset) this.options.attr = attr;
111
+ attr(attr, reset = false) {
112
+ if (reset) this.options.attr = attr;
106
113
  else this.options.attr = { ...this.options.attr, ...attr };
107
114
  return this.update();
108
115
  }
109
116
 
110
- style(style, reset = false){
111
- if(reset) this.options.style = style;
117
+ style(style, reset = false) {
118
+ if (reset) this.options.style = style;
112
119
  else this.options.style = { ...this.options.style, ...style };
113
120
  return this.update();
114
121
  }
115
122
 
116
- add(child){
123
+ add(child) {
117
124
  this.options.children.push(child);
118
125
  return this.update();
119
126
  }
120
127
 
121
- remove(childId, recursive = true){
122
- const child = typeof childId == "string" ? this.find(childId, recursive) : childId;
123
- if(!child) return this;
124
- if(recursive && child.parent !== this){
128
+ remove(childId, recursive = true) {
129
+ const child =
130
+ typeof childId == "string" ? this.find(childId, recursive) : childId;
131
+ if (!child) return this;
132
+ if (recursive && child.parent !== this) {
125
133
  child.parent.remove(child);
126
134
  } else {
127
135
  this.options.children.splice(this.options.children.indexOf(child), 1);
@@ -129,31 +137,30 @@ module.exports.uiClasses = (context, options, send, recieve, hook, rmHook) => {
129
137
  }
130
138
  return this;
131
139
  }
132
-
133
140
  }
134
141
 
135
142
  class RewTextWidget extends RewWidget {
136
- constructor(text = '', options = RemWidgetOptions({})){
143
+ constructor(text = "", options = RemWidgetOptions({})) {
137
144
  super({
138
145
  ...options,
139
- data: { ...(options.data), text }
146
+ data: { ...options.data, text },
140
147
  });
141
148
  }
142
149
  }
143
150
 
144
151
  class StyleSheet {
145
- constructor(css = ''){
146
- send({ action: 'addStyleSheet', data: css });
152
+ constructor(css = "") {
153
+ send({ action: "addStyleSheet", data: css });
147
154
  }
148
155
  }
149
156
 
150
- function findElement(id){
157
+ function findElement(id) {
151
158
  return new Promise((r) => {
152
159
  const rid = generateRandomID();
153
- hook(rid, 'findElement', (data) => {
154
- r(CreatedElements.find(e => e.uuid == data.uuid) || data);
160
+ hook(rid, "findElement", (data) => {
161
+ r(CreatedElements.find((e) => e.uuid == data.uuid) || data);
155
162
  });
156
- send({ action: 'findElement', data: { id, rid } });
163
+ send({ action: "findElement", data: { id, rid } });
157
164
  });
158
165
  }
159
166
 
@@ -165,9 +172,9 @@ module.exports.uiClasses = (context, options, send, recieve, hook, rmHook) => {
165
172
  // }, false);
166
173
 
167
174
  const Transmitter = {
168
- send: (data) => send({ action: 'message', data }),
169
- recieve: (cb) => recieve((data) => cb(data.data))
170
- }
175
+ send: (data) => send({ action: "message", data }),
176
+ recieve: (cb) => recieve((data) => cb(data.data)),
177
+ };
171
178
 
172
179
  return {
173
180
  Widget: RewWidget,
@@ -175,6 +182,6 @@ module.exports.uiClasses = (context, options, send, recieve, hook, rmHook) => {
175
182
  WidgetOptions: RemWidgetOptions,
176
183
  findElement,
177
184
  StyleSheet: StyleSheet,
178
- Transmitter
179
- }
180
- }
185
+ Transmitter,
186
+ };
187
+ };
@@ -1,13 +1,12 @@
1
1
  const path = require("path");
2
2
  const fs = require("fs");
3
3
 
4
-
5
4
  module.exports = {
6
5
  findPackage(pkg) {
7
- if(pkg == 'pkgs') return false;
8
- return fs.existsSync(path.resolve(__dirname, './'+pkg+'.js'));
6
+ if (pkg == "pkgs") return false;
7
+ return fs.existsSync(path.resolve(__dirname, "./" + pkg + ".js"));
8
+ },
9
+ getPackage(pkg) {
10
+ return require("./" + pkg);
9
11
  },
10
- getPackage(pkg){
11
- return require('./'+pkg);
12
- }
13
12
  };
@@ -0,0 +1,437 @@
1
+ const fs = require("fs");
2
+ const { v4: uuidv4 } = require("uuid");
3
+ const path = require("path");
4
+ const msgpack = require("tiny-msgpack");
5
+ const crypto = require("crypto");
6
+ const { CONFIG_PATH } = require("../const/config_path");
7
+
8
+ const ENCRYPTION_KEY =
9
+ "e6ad8b0792b9e0472ea44d1f3adfd1d503182efcce25991b05cc5ef83f307ffc";
10
+
11
+ class Change {
12
+ constructor(values) {
13
+ this.values = values;
14
+ }
15
+ }
16
+
17
+ class PopChange extends Change {}
18
+
19
+ class PushChange extends Change {}
20
+
21
+ const runePush = (...values) => new PushChange(values);
22
+ const runePop = (...values) => new PopChange(values);
23
+
24
+ function makeRef(value, props = "") {
25
+ if (!value["@rune.id"]) return null;
26
+ const collection = getCollectionFromID(value["@rune.id"]);
27
+ const ref = collection + "." + value["@rune.id"];
28
+ return "@rune.ref " + ref + props;
29
+ }
30
+
31
+ const eid = (s, diff) =>
32
+ s
33
+ .split("")
34
+ .map((i) => {
35
+ let charCode = i.charCodeAt(0) + diff;
36
+ if (charCode > 122) {
37
+ charCode -= 26;
38
+ }
39
+ return String.fromCharCode(charCode);
40
+ })
41
+ .join("");
42
+
43
+ function generateID(id, collection) {
44
+ return eid(collection, 5) + "+" + id;
45
+ }
46
+
47
+ function getCollectionFromID(id) {
48
+ return eid(id.split("+")[0], -5);
49
+ }
50
+
51
+ const createDB = (dbName, dirname, dbData = {}, encryptionKey) => {
52
+ const dbDirPath = path.join(dirname, dbName);
53
+ const mainFilePath = path.join(dbDirPath, "main.bin");
54
+ const algorithm = "aes-256-ctr";
55
+
56
+ if (!fs.existsSync(dbDirPath)) {
57
+ fs.mkdirSync(dbDirPath);
58
+ }
59
+
60
+ const encrypt = (data) => {
61
+ const iv = crypto.randomBytes(16);
62
+ const cipher = crypto.createCipheriv(
63
+ algorithm,
64
+ Buffer.from(encryptionKey, "hex"),
65
+ iv,
66
+ );
67
+ const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
68
+ return Buffer.concat([iv, encrypted]);
69
+ };
70
+
71
+ const decrypt = (data) => {
72
+ const iv = data.slice(0, 16);
73
+ const encryptedData = data.slice(16);
74
+ const decipher = crypto.createDecipheriv(
75
+ algorithm,
76
+ Buffer.from(encryptionKey, "hex"),
77
+ iv,
78
+ );
79
+ const decrypted = Buffer.concat([
80
+ decipher.update(encryptedData),
81
+ decipher.final(),
82
+ ]);
83
+ return decrypted;
84
+ };
85
+
86
+ const serializeData = (data) => {
87
+ return msgpack.encode(data);
88
+ };
89
+
90
+ const deserializeData = (buffer) => {
91
+ return msgpack.decode(decrypt(buffer));
92
+ };
93
+
94
+ const getData = () => {
95
+ return readMainData().data;
96
+ };
97
+ getData.key = (key) => {
98
+ return getData()[key];
99
+ };
100
+
101
+ const setData = (data) => {
102
+ const newData = readMainData();
103
+ for (let i in data) if (data[i] !== undefined) newData.data[i] = data[i];
104
+ writeMainData(newData);
105
+ };
106
+
107
+ setData.key = (key, value) => {
108
+ setData({ [key]: value });
109
+ };
110
+
111
+ setData.rm = (key) => {
112
+ setData({ [key]: undefined });
113
+ };
114
+
115
+ setData.reset = () => {
116
+ writeMainData({
117
+ ...readMainData(),
118
+ data: { ...dbData, name: dbName },
119
+ });
120
+ };
121
+
122
+ const readMainData = () => {
123
+ if (!fs.existsSync(mainFilePath)) {
124
+ writeMainData({
125
+ collections: [],
126
+ data: { ...dbData, name: dbName },
127
+ maps: [],
128
+ });
129
+ }
130
+ const buffer = fs.readFileSync(mainFilePath);
131
+ return deserializeData(buffer);
132
+ };
133
+
134
+ const writeMainData = (data) => {
135
+ const buffer = encrypt(serializeData(data));
136
+ fs.writeFileSync(mainFilePath, buffer);
137
+ };
138
+
139
+ const readDataFile = (filePath) => {
140
+ const buffer = fs.readFileSync(filePath);
141
+ return deserializeData(buffer);
142
+ };
143
+
144
+ const writeDataFile = (filePath, data) => {
145
+ const buffer = encrypt(serializeData(data));
146
+ fs.writeFileSync(filePath, buffer);
147
+ };
148
+
149
+ const collection = (collectionName) => {
150
+ const collectionFilePath = path.join(dbDirPath, `${collectionName}.col`);
151
+
152
+ const insert = (record) => {
153
+ const mainData = readMainData();
154
+ if (!mainData.collections.includes(collectionName)) {
155
+ mainData.collections.push(collectionName);
156
+ writeMainData(mainData);
157
+ }
158
+
159
+ let data = [];
160
+ if (fs.existsSync(collectionFilePath)) {
161
+ data = readDataFile(collectionFilePath);
162
+ }
163
+ const id = uuidv4();
164
+ record["@rune.id"] = generateID(id, collectionName);
165
+ data.push(record);
166
+ writeDataFile(collectionFilePath, data);
167
+ return record;
168
+ };
169
+
170
+ const read = (id, evaluate = true) => {
171
+ if (typeof id == "object" && "@rune.id" in id) id = id["@rune.id"];
172
+ if (!fs.existsSync(collectionFilePath)) return null;
173
+ const data = readDataFile(collectionFilePath);
174
+ const record = data.find((record) => record["@rune.id"] === id);
175
+ if (record) {
176
+ return evaluateRecord(record);
177
+ }
178
+ return null;
179
+ };
180
+
181
+ const evaluateRecord = (record, prevRecord) => {
182
+ const evaluateValue = (val) => {
183
+ if (typeof val == "string" && val.startsWith("@rune.ref")) {
184
+ const ref = val.split("@rune.ref")[1].trim();
185
+ const refData = findRef(ref, false);
186
+ if (!refData) {
187
+ return null;
188
+ } else {
189
+ let value = refData;
190
+ if (refData["@rune.id"]) {
191
+ value =
192
+ prevRecord && prevRecord["@rune.id"] == refData["@rune.id"]
193
+ ? prevRecord
194
+ : evaluateRecord(refData, record);
195
+ }
196
+ return value;
197
+ }
198
+ }
199
+ if (Array.isArray(val)) {
200
+ val = val.map((i) => evaluateValue(i));
201
+ }
202
+ return val;
203
+ };
204
+ for (let i in record) {
205
+ const val = record[i];
206
+ record[i] = evaluateValue(val);
207
+ }
208
+ return record;
209
+ };
210
+
211
+ const update = (caseRecord, newRecord) => {
212
+ let id;
213
+ if (typeof caseRecord === "string") {
214
+ id = caseRecord;
215
+ } else if (typeof caseRecord === "object") {
216
+ const data = readDataFile(collectionFilePath);
217
+ const record = data.find((record) => {
218
+ for (const key in caseRecord) {
219
+ if (record[key] !== caseRecord[key]) return false;
220
+ }
221
+ return true;
222
+ });
223
+ if (record) {
224
+ id = record["@rune.id"];
225
+ } else {
226
+ return null; // No matching record found
227
+ }
228
+ }
229
+
230
+ if (!id) return null;
231
+
232
+ const data = readDataFile(collectionFilePath);
233
+ const index = data.findIndex((record) => record["@rune.id"] === id);
234
+ if (index !== -1) {
235
+ const oldRecord = data[index];
236
+ for (const key in newRecord) {
237
+ const value = newRecord[key];
238
+ if (value instanceof PushChange) {
239
+ if (!oldRecord[key] || !Array.isArray(oldRecord[key])) {
240
+ oldRecord[key] = [];
241
+ }
242
+ oldRecord[key].push(...value.values);
243
+ } else if (value instanceof PopChange) {
244
+ if (oldRecord[key] && Array.isArray(oldRecord[key])) {
245
+ value.values.forEach((val) => {
246
+ const index = oldRecord[key].indexOf(val);
247
+ if (index !== -1) {
248
+ oldRecord[key].splice(index, 1);
249
+ }
250
+ });
251
+ }
252
+ } else {
253
+ oldRecord[key] = value;
254
+ }
255
+ }
256
+ data[index] = oldRecord;
257
+ writeDataFile(collectionFilePath, data);
258
+ return data[index];
259
+ }
260
+ return null;
261
+ };
262
+
263
+ const find = (criteria) => {
264
+ if (typeof criteria == "string") return read(criteria);
265
+ if (!criteria || typeof criteria !== "object") return null;
266
+
267
+ const data = readDataFile(collectionFilePath);
268
+ const record =
269
+ data.find((record) => {
270
+ for (const key in criteria) {
271
+ if (record[key] !== criteria[key]) return false;
272
+ }
273
+ return true;
274
+ }) || null;
275
+ if (record) {
276
+ return evaluateRecord(record);
277
+ }
278
+ return null;
279
+ };
280
+
281
+ const remove = (id) => {
282
+ if ("@rune.id" in id) id = id["@rune.id"];
283
+ if (!fs.existsSync(collectionFilePath)) return false;
284
+ let data = readDataFile(collectionFilePath);
285
+ const index = data.findIndex((record) => record["@rune.id"] === id);
286
+ if (index !== -1) {
287
+ data.splice(index, 1);
288
+ writeDataFile(collectionFilePath, data);
289
+ return true;
290
+ }
291
+ return false;
292
+ };
293
+
294
+ const list = () => {
295
+ if (!fs.existsSync(collectionFilePath)) return [];
296
+ const data = readDataFile(collectionFilePath);
297
+ return data.map((rec) => evaluateRecord(rec));
298
+ };
299
+
300
+ const map = (cb, mutate = false) => {
301
+ const data = readDataFile(collectionFilePath);
302
+ const mappedData = data.map(cb);
303
+ if (mutate) {
304
+ writeDataFile(collectionFilePath, mappedData);
305
+ }
306
+ return mappedData;
307
+ };
308
+
309
+ const transform = (cb, mutate = true) => {
310
+ const data = readDataFile(collectionFilePath);
311
+ const transformedData = cb(data);
312
+ if (mutate) {
313
+ writeDataFile(collectionFilePath, transformedData);
314
+ }
315
+ return transformedData;
316
+ };
317
+
318
+ const filter = (cb, mutate = false) => {
319
+ const data = readDataFile(collectionFilePath);
320
+ const filteredData = data.filter(cb);
321
+ if (mutate) {
322
+ writeDataFile(collectionFilePath, filteredData);
323
+ }
324
+ return filteredData;
325
+ };
326
+
327
+ const sort = (cb, mutate = false) => {
328
+ const data = readDataFile(collectionFilePath);
329
+ const sortedData = data.sort(cb);
330
+ if (mutate) {
331
+ writeDataFile(collectionFilePath, sortedData);
332
+ }
333
+ return sortedData;
334
+ };
335
+
336
+ return {
337
+ insert,
338
+ read,
339
+ update,
340
+ remove,
341
+ find,
342
+ map,
343
+ transform,
344
+ filter,
345
+ sort,
346
+ list,
347
+ };
348
+ };
349
+
350
+ const findRef = (ref, evaluate = true) => {
351
+ const [name, id, ...rest] = ref.split(".");
352
+ const col = collection(name);
353
+ const record = col.read(id, evaluate);
354
+ if (rest.length === 0) return record;
355
+ let value = record;
356
+ for (const prop of rest) {
357
+ if (typeof value != "object") break;
358
+ if (!(prop in value)) return null;
359
+ value = value[prop];
360
+ }
361
+ return value;
362
+ };
363
+
364
+ const map = (mapName) => {
365
+ const mapFilePath = path.join(dbDirPath, `${mapName}.map`);
366
+
367
+ const set = (key, value) => {
368
+ const mainData = readMainData();
369
+ if (!mainData.maps.includes(mapName)) {
370
+ mainData.maps.push(mapName);
371
+ writeMainData(mainData);
372
+ }
373
+
374
+ let data = {};
375
+ if (fs.existsSync(mapFilePath)) {
376
+ data = readDataFile(mapFilePath);
377
+ }
378
+ data[key] = value;
379
+ writeDataFile(mapFilePath, data);
380
+ };
381
+
382
+ const get = (key) => {
383
+ if (!fs.existsSync(mapFilePath)) return null;
384
+ const data = readDataFile(mapFilePath);
385
+ return data[key] || null;
386
+ };
387
+
388
+ const remove = (key) => {
389
+ if (!fs.existsSync(mapFilePath)) return false;
390
+ const data = readDataFile(mapFilePath);
391
+ if (data[key]) {
392
+ delete data[key];
393
+ writeDataFile(mapFilePath, data);
394
+ return true;
395
+ }
396
+ return false;
397
+ };
398
+
399
+ const transform = (cb, mutate = false) => {
400
+ const data = readDataFile(mapFilePath);
401
+ const transformedData = cb(data);
402
+ if (mutate) {
403
+ writeDataFile(mapFilePath, transformedData);
404
+ }
405
+ return transformedData;
406
+ };
407
+
408
+ const list = () => {
409
+ if (!fs.existsSync(mapFilePath)) return {};
410
+ const data = readDataFile(mapFilePath);
411
+ return data;
412
+ };
413
+
414
+ return { set, get, remove, list, transform };
415
+ };
416
+
417
+ readMainData();
418
+
419
+ return { setData, getData, collection, findRef, makeRef, map };
420
+ };
421
+
422
+ module.exports = (context) => ({
423
+ _onImport() {
424
+ delete this.createDB;
425
+ return this;
426
+ },
427
+ db(dbname, data = {}, encryptionKey) {
428
+ if (!context.app) throw new Error("rune can only be used in apps");
429
+ const pkg = path.join(CONFIG_PATH, context.app.config.package, "db");
430
+ if (!fs.existsSync(pkg)) fs.mkdirSync(pkg, { recursive: true });
431
+ return createDB(dbname, pkg, data, encryptionKey || ENCRYPTION_KEY);
432
+ },
433
+ makeRef,
434
+ runePop,
435
+ runePush,
436
+ createDB,
437
+ });