@muze-nl/simplystore 0.4.7 → 0.5.1
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/package.json +14 -7
- package/scripts/convert.mjs +25 -0
- package/src/command-worker-module.mjs +100 -0
- package/src/command-worker.mjs +13 -0
- package/src/fastParse.mjs +1036 -0
- package/src/fastStringify.mjs +200 -0
- package/src/load-worker.mjs +33 -0
- package/src/{worker-query.mjs → query-worker-module.mjs} +138 -83
- package/src/query-worker.mjs +12 -0
- package/src/server.mjs +303 -218
- package/src/statusCodes.mjs +70 -0
- package/src/symbols.mjs +6 -0
- package/src/util.mjs +3 -3
- package/src/workerPool.mjs +99 -0
- package/data.jsontag +0 -20
- package/src/share.mjs +0 -142
- package/src/worker-query-init.mjs +0 -14
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import JSONTag from '@muze-nl/jsontag';
|
|
2
|
+
import {source,isProxy,getIndex, getBuffer} from './symbols.mjs'
|
|
3
|
+
|
|
4
|
+
// faststringify function for a fast parseable arraybuffer output
|
|
5
|
+
//
|
|
6
|
+
const encoder = new TextEncoder()
|
|
7
|
+
const decoder = new TextDecoder()
|
|
8
|
+
|
|
9
|
+
export default function stringify(value, meta, skipLength=false, index) {
|
|
10
|
+
let resultArray = []
|
|
11
|
+
if (!meta) {
|
|
12
|
+
meta = {}
|
|
13
|
+
}
|
|
14
|
+
if (!meta.index) {
|
|
15
|
+
meta.index = {}
|
|
16
|
+
}
|
|
17
|
+
if (!meta.index.id) {
|
|
18
|
+
meta.index.id = new Map()
|
|
19
|
+
}
|
|
20
|
+
let references = new WeakMap()
|
|
21
|
+
|
|
22
|
+
const innerStringify = (value) => {
|
|
23
|
+
let indent = ""
|
|
24
|
+
let gap = ""
|
|
25
|
+
|
|
26
|
+
if (typeof space === "number") {
|
|
27
|
+
indent += " ".repeat(space)
|
|
28
|
+
} else if (typeof space === "string") {
|
|
29
|
+
indent = space
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const encodeProperties = (obj) => {
|
|
33
|
+
return Object.getOwnPropertyNames(obj).map(prop => {
|
|
34
|
+
let enumerable = obj.propertyIsEnumerable(prop) ? '' : '#'
|
|
35
|
+
return enumerable+'"'+prop+'":'+str(prop, obj)
|
|
36
|
+
}).join(',')
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const encodeEntries = (arr) => {
|
|
40
|
+
let result = arr.map((value,index) => {
|
|
41
|
+
return str(index, arr)
|
|
42
|
+
}).join(",")
|
|
43
|
+
return result
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const createId = (value) => {
|
|
47
|
+
if (typeof crypto === 'undefined') {
|
|
48
|
+
console.error('JSONTag: cannot generate uuid, crypto support is disabled.')
|
|
49
|
+
throw new Error('Cannot create links to resolve references, crypto support is disabled')
|
|
50
|
+
}
|
|
51
|
+
if (typeof crypto.randomUUID === 'function') {
|
|
52
|
+
var id = crypto.randomUUID()
|
|
53
|
+
} else {
|
|
54
|
+
var id = ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
|
|
55
|
+
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
JSONTag.setAttribute(value, 'id', id)
|
|
59
|
+
return id
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const encoder = new TextEncoder()
|
|
63
|
+
const decoder = new TextDecoder()
|
|
64
|
+
|
|
65
|
+
const str = (key, holder) => {
|
|
66
|
+
let value = holder[key]
|
|
67
|
+
let result, updateReference
|
|
68
|
+
// if value is a valueProxy, just copy the input slice
|
|
69
|
+
if (value && !JSONTag.isNull(value) && value[isProxy]) {
|
|
70
|
+
if (index===0) {
|
|
71
|
+
resultArray.push(decoder.decode(value[getBuffer](index)))
|
|
72
|
+
}
|
|
73
|
+
return decoder.decode(value[getBuffer](index))
|
|
74
|
+
}
|
|
75
|
+
if (typeof value === 'undefined' || value === null) {
|
|
76
|
+
return 'null'
|
|
77
|
+
}
|
|
78
|
+
if (JSONTag.getType(value) === 'object' && !Array.isArray(value)) {
|
|
79
|
+
let id = JSONTag.getAttribute(value, 'id')
|
|
80
|
+
if (!references.has(value)) {
|
|
81
|
+
let reference = resultArray.length
|
|
82
|
+
updateReference = reference
|
|
83
|
+
references.set(value, updateReference)
|
|
84
|
+
resultArray.push('')
|
|
85
|
+
if (id && !meta.index.id.has(id)) {
|
|
86
|
+
meta.index.id.set(id, updateReference)
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
return '~'+references.get(value)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (Array.isArray(value)) {
|
|
93
|
+
result = JSONTag.getTypeString(value) + "["+encodeEntries(value)+"]"
|
|
94
|
+
} else if (value instanceof Object) {
|
|
95
|
+
let typeString = JSONTag.getTypeString(value)
|
|
96
|
+
let type = JSONTag.getType(value)
|
|
97
|
+
switch (type) {
|
|
98
|
+
case 'string':
|
|
99
|
+
case 'decimal':
|
|
100
|
+
case 'money':
|
|
101
|
+
case 'link':
|
|
102
|
+
case 'text':
|
|
103
|
+
case 'blob':
|
|
104
|
+
case 'color':
|
|
105
|
+
case 'email':
|
|
106
|
+
case 'hash':
|
|
107
|
+
case 'duration':
|
|
108
|
+
case 'phone':
|
|
109
|
+
case 'url':
|
|
110
|
+
case 'uuid':
|
|
111
|
+
case 'date':
|
|
112
|
+
case 'time':
|
|
113
|
+
case 'datetime':
|
|
114
|
+
if (JSONTag.isNull(value)) {
|
|
115
|
+
value = 'null'
|
|
116
|
+
} else {
|
|
117
|
+
value = JSON.stringify(''+value)
|
|
118
|
+
}
|
|
119
|
+
result = typeString + value
|
|
120
|
+
break
|
|
121
|
+
case 'int':
|
|
122
|
+
case 'uint':
|
|
123
|
+
case 'int8':
|
|
124
|
+
case 'uint8':
|
|
125
|
+
case 'int16':
|
|
126
|
+
case 'uint16':
|
|
127
|
+
case 'int32':
|
|
128
|
+
case 'uint32':
|
|
129
|
+
case 'int64':
|
|
130
|
+
case 'uint64':
|
|
131
|
+
case 'float':
|
|
132
|
+
case 'float32':
|
|
133
|
+
case 'float64':
|
|
134
|
+
case 'timestamp':
|
|
135
|
+
case 'number':
|
|
136
|
+
case 'boolean':
|
|
137
|
+
if (JSONTag.isNull(value)) {
|
|
138
|
+
value = 'null'
|
|
139
|
+
} else {
|
|
140
|
+
value = JSON.stringify(value)
|
|
141
|
+
}
|
|
142
|
+
result = typeString + value
|
|
143
|
+
break
|
|
144
|
+
case 'array':
|
|
145
|
+
let entries = encodeEntries(value) // calculate children first so parent references can add id attribute
|
|
146
|
+
result = typeString + '[' + entries + '}'
|
|
147
|
+
break
|
|
148
|
+
case 'object':
|
|
149
|
+
if (JSONTag.isNull(value)) {
|
|
150
|
+
result = typeString + "null"
|
|
151
|
+
} else {
|
|
152
|
+
let props = encodeProperties(value); // calculate children first so parent references can add id attribute
|
|
153
|
+
result = typeString + '{' + props + '}'
|
|
154
|
+
}
|
|
155
|
+
break
|
|
156
|
+
default:
|
|
157
|
+
throw new Error(JSONTag.getType(value)+' type not yet implemented')
|
|
158
|
+
break
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
result = JSON.stringify(value)
|
|
162
|
+
}
|
|
163
|
+
if (typeof updateReference != 'undefined') {
|
|
164
|
+
resultArray[updateReference] = result
|
|
165
|
+
if (index!==updateReference) {
|
|
166
|
+
result = '~'+updateReference
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return result
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return str("", {"": value})
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const encode = (s) => {
|
|
176
|
+
if (skipLength) {
|
|
177
|
+
return s
|
|
178
|
+
}
|
|
179
|
+
let length = new Blob([s]).size
|
|
180
|
+
return '('+length+')'+s
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
innerStringify(value)
|
|
184
|
+
return resultArray.map(encode).join("\n")
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export function stringToSAB(strData) {
|
|
188
|
+
const buffer = encoder.encode(strData)
|
|
189
|
+
const sab = new SharedArrayBuffer(buffer.length)
|
|
190
|
+
let uint8sab = new Uint8Array(sab)
|
|
191
|
+
uint8sab.set(buffer,0)
|
|
192
|
+
return uint8sab
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export function resultSetStringify(resultSet) {
|
|
196
|
+
return resultSet.map((e,i) => {
|
|
197
|
+
let buffer = e[getBuffer](i)
|
|
198
|
+
return '('+buffer.length+')'+decoder.decode(buffer)
|
|
199
|
+
}).join("\n")
|
|
200
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { parentPort } from 'node:worker_threads'
|
|
2
|
+
import JSONTag from '@muze-nl/jsontag'
|
|
3
|
+
import fastParse from './fastParse.mjs'
|
|
4
|
+
import fs from 'fs'
|
|
5
|
+
import {resultSetStringify,stringToSAB} from './fastStringify.mjs'
|
|
6
|
+
import {source} from '../src/symbols.mjs'
|
|
7
|
+
|
|
8
|
+
parentPort.on('message', datafile => {
|
|
9
|
+
const jsontag = fs.readFileSync(datafile)
|
|
10
|
+
let meta = {
|
|
11
|
+
index: {
|
|
12
|
+
id: new Map()
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const data = fastParse(jsontag)
|
|
16
|
+
|
|
17
|
+
// fastParse doesn't create meta.index.id, so do that here
|
|
18
|
+
let length = data.length
|
|
19
|
+
for (let i=0; i<length; i++) {
|
|
20
|
+
let id=JSONTag.getAttribute(data[i][source],'id')
|
|
21
|
+
if (id) {
|
|
22
|
+
meta.index.id.set(id,i)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const strData = resultSetStringify(data)
|
|
27
|
+
const sab = stringToSAB(strData)
|
|
28
|
+
|
|
29
|
+
parentPort.postMessage({
|
|
30
|
+
data: sab,
|
|
31
|
+
meta
|
|
32
|
+
})
|
|
33
|
+
})
|
|
@@ -1,96 +1,63 @@
|
|
|
1
|
-
import JSONTag from
|
|
2
|
-
import
|
|
1
|
+
import JSONTag from '@muze-nl/jsontag'
|
|
2
|
+
import fastParse from './fastParse.mjs'
|
|
3
|
+
import {source, isProxy} from './symbols.mjs'
|
|
3
4
|
import {_,from,not,anyOf,allOf,asc,desc,sum,count,avg,max,min} from 'array-where-select'
|
|
4
|
-
import
|
|
5
|
+
import pointer from 'json-pointer'
|
|
5
6
|
import {VM} from 'vm2'
|
|
7
|
+
import { memoryUsage } from 'node:process'
|
|
6
8
|
|
|
7
|
-
let
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
meta = m
|
|
9
|
+
let resultSet = []
|
|
10
|
+
let dataspace
|
|
11
|
+
let meta = {}
|
|
12
|
+
let metaProxy = {
|
|
13
|
+
index: {
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
let result
|
|
22
|
-
if (path) {
|
|
23
|
-
//jsonpointer doesn't allow an empty pointer
|
|
24
|
-
try {
|
|
25
|
-
if (pointer.has(dataspace, path)) {
|
|
26
|
-
result = pointer.get(dataspace, path)
|
|
27
|
-
} else {
|
|
28
|
-
result = JSONTag.parse('<object class="Error">{"message":"Not found", "code":404}')
|
|
29
|
-
}
|
|
30
|
-
} catch(err) {
|
|
31
|
-
result = JSONTag.parse('<object class="Error">{"message":'+JSON.stringify(err.message)+', "code":500}')
|
|
17
|
+
const metaIdProxy = {
|
|
18
|
+
get: (id) => {
|
|
19
|
+
let index = meta.index.id.get(id)
|
|
20
|
+
if (index || index===0) {
|
|
21
|
+
return resultSet[index]
|
|
32
22
|
}
|
|
33
|
-
}
|
|
34
|
-
|
|
23
|
+
},
|
|
24
|
+
has: (id) => {
|
|
25
|
+
return meta.index.id.has(id)
|
|
35
26
|
}
|
|
36
|
-
return [result,path]
|
|
37
27
|
}
|
|
38
28
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
})
|
|
46
|
-
} else if (type === 'link') {
|
|
47
|
-
// do nothing
|
|
48
|
-
} else if (data && typeof data === 'object') {
|
|
49
|
-
data = JSONTag.clone(data)
|
|
50
|
-
Object.keys(data).forEach(key => {
|
|
51
|
-
if (Array.isArray(data[key])) {
|
|
52
|
-
data[key] = new JSONTag.Link(baseURL+key+'/')
|
|
53
|
-
} else if (data[key] && typeof data[key] === 'object') {
|
|
54
|
-
if (JSONTag.getType(data[key])!=='link') {
|
|
55
|
-
let id=JSONTag.getAttribute(data[key], 'id')
|
|
56
|
-
if (!id) {
|
|
57
|
-
id = baseURL+key+'/'
|
|
58
|
-
}
|
|
59
|
-
data[key] = new JSONTag.Link(id)
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
})
|
|
63
|
-
}
|
|
64
|
-
return data
|
|
29
|
+
const FastJSONTag = {
|
|
30
|
+
getType: (obj) => JSONTag.getType(obj[source]),
|
|
31
|
+
getAttribute: (obj, attr) => JSONTag.getAttribute(obj[source],attr),
|
|
32
|
+
getAttributes: (obj) => JSONTag.getAttributes(obj[source]),
|
|
33
|
+
getAttributeString: (obj) => JSONTag.getAttributesString(obj[source]),
|
|
34
|
+
getTypeString: (obj) => JSONTag.getTypeString(obj[source])
|
|
65
35
|
}
|
|
66
36
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
37
|
+
const tasks = {
|
|
38
|
+
init: async (task) => {
|
|
39
|
+
resultSet = fastParse(task.req.body)
|
|
40
|
+
dataspace = resultSet[0]
|
|
41
|
+
meta = task.req.meta
|
|
42
|
+
metaProxy.index.id = metaIdProxy
|
|
43
|
+
//@TODO: add references and baseURL
|
|
44
|
+
return true
|
|
45
|
+
},
|
|
46
|
+
query: async (task) => {
|
|
47
|
+
return runQuery(task.req.path, task.req, task.req.body)
|
|
48
|
+
},
|
|
49
|
+
memoryUsage: async () => {
|
|
50
|
+
let result = memoryUsage()
|
|
51
|
+
console.log('memory',result)
|
|
52
|
+
return result
|
|
79
53
|
}
|
|
80
54
|
}
|
|
81
55
|
|
|
82
|
-
export
|
|
83
|
-
if (!jsontag) { throw new Error('missing jsontag parameter')}
|
|
84
|
-
dataspace = jsontag
|
|
85
|
-
meta = m
|
|
86
|
-
deepFreeze(dataspace)
|
|
87
|
-
return true
|
|
88
|
-
}
|
|
56
|
+
export default tasks
|
|
89
57
|
|
|
90
|
-
export function runQuery(
|
|
58
|
+
export function runQuery(pointer, request, query) {
|
|
91
59
|
if (!pointer) { throw new Error('missing pointer parameter')}
|
|
92
60
|
if (!request) { throw new Error('missing request parameter')}
|
|
93
|
-
console.log('query',pointer)
|
|
94
61
|
let response = {
|
|
95
62
|
jsontag: request.jsontag
|
|
96
63
|
}
|
|
@@ -98,8 +65,6 @@ export function runQuery({pointer, request, query}) {
|
|
|
98
65
|
|
|
99
66
|
if (query) {
|
|
100
67
|
// @todo add text search: https://github.com/nextapps-de/flexsearch
|
|
101
|
-
// @todo add tree walk map/reduce/find/filter style functions
|
|
102
|
-
// @todo add arc tree dive function?
|
|
103
68
|
// @todo replace VM with V8 isolate
|
|
104
69
|
const vm = new VM({
|
|
105
70
|
timeout: 1000,
|
|
@@ -107,7 +72,7 @@ export function runQuery({pointer, request, query}) {
|
|
|
107
72
|
sandbox: {
|
|
108
73
|
root: dataspace, //@TODO: if we don't pass the root, we can later shard
|
|
109
74
|
data: result,
|
|
110
|
-
meta,
|
|
75
|
+
meta: metaProxy,
|
|
111
76
|
_,
|
|
112
77
|
from,
|
|
113
78
|
not,
|
|
@@ -119,15 +84,15 @@ export function runQuery({pointer, request, query}) {
|
|
|
119
84
|
count,
|
|
120
85
|
avg,
|
|
121
86
|
max,
|
|
122
|
-
min,
|
|
87
|
+
min,
|
|
123
88
|
// console: connectConsole(res),
|
|
124
|
-
JSONTag,
|
|
89
|
+
JSONTag: FastJSONTag,
|
|
125
90
|
request
|
|
126
91
|
},
|
|
127
92
|
wasm: false
|
|
128
93
|
})
|
|
129
94
|
try {
|
|
130
|
-
result = vm.run(query)
|
|
95
|
+
result = deProxy(vm.run(query))
|
|
131
96
|
let used = Math.round(process.memoryUsage().heapUsed / 1024 / 1024);
|
|
132
97
|
console.log(`(${used} MB)`);
|
|
133
98
|
} catch(err) {
|
|
@@ -144,10 +109,100 @@ export function runQuery({pointer, request, query}) {
|
|
|
144
109
|
}
|
|
145
110
|
if (!response.code) {
|
|
146
111
|
if (response.jsontag) {
|
|
147
|
-
|
|
112
|
+
try {
|
|
113
|
+
response.body = JSONTag.stringify(result)
|
|
114
|
+
} catch(err) {
|
|
115
|
+
console.log(err)
|
|
116
|
+
response.code = 500
|
|
117
|
+
response.body = '<object class="Error">{"message":'+JSON.stringify(''+err)+',"code":500}'
|
|
118
|
+
}
|
|
148
119
|
} else {
|
|
120
|
+
//@FIXME: replace recursive links
|
|
149
121
|
response.body = JSON.stringify(result)
|
|
150
122
|
}
|
|
151
123
|
}
|
|
152
124
|
return response
|
|
153
|
-
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function getDataSpace(path, dataspace) {
|
|
128
|
+
if (path.substring(path.length-1)==='/') {
|
|
129
|
+
//jsonpointer doesn't allow a trailing '/'
|
|
130
|
+
path = path.substring(0, path.length-1)
|
|
131
|
+
}
|
|
132
|
+
let result
|
|
133
|
+
if (path) {
|
|
134
|
+
//jsonpointer doesn't allow an empty pointer
|
|
135
|
+
try {
|
|
136
|
+
if (pointer.has(dataspace, path)) {
|
|
137
|
+
result = pointer.get(dataspace, path)
|
|
138
|
+
} else {
|
|
139
|
+
result = JSONTag.parse('<object class="Error">{"message":"Not found", "code":404}')
|
|
140
|
+
}
|
|
141
|
+
} catch(err) {
|
|
142
|
+
result = JSONTag.parse('<object class="Error">{"message":'+JSON.stringify(err.message)+', "code":500}')
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
result = dataspace
|
|
146
|
+
}
|
|
147
|
+
return [result,path]
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function linkReplacer(data, baseURL) {
|
|
151
|
+
let type = JSONTag.getType(data)
|
|
152
|
+
let attributes = JSONTag.getAttributes(data)
|
|
153
|
+
if (Array.isArray(data)) {
|
|
154
|
+
data = data.map((entry,index) => {
|
|
155
|
+
return linkReplacer(data[index], baseURL+index+'/')
|
|
156
|
+
})
|
|
157
|
+
} else if (type === 'link') {
|
|
158
|
+
// do nothing
|
|
159
|
+
} else if (data && typeof data === 'object') {
|
|
160
|
+
if (data[source]) {
|
|
161
|
+
data = data[source]
|
|
162
|
+
}
|
|
163
|
+
data = JSONTag.clone(data)
|
|
164
|
+
Object.keys(data).forEach(key => {
|
|
165
|
+
if (Array.isArray(data[key])) {
|
|
166
|
+
data[key] = new JSONTag.Link(baseURL+key+'/')
|
|
167
|
+
} else if (data[key] && typeof data[key] === 'object') {
|
|
168
|
+
if (JSONTag.getType(data[key])!=='link') {
|
|
169
|
+
let id=JSONTag.getAttribute(data[key], 'id')
|
|
170
|
+
if (!id) {
|
|
171
|
+
id = baseURL+key+'/'
|
|
172
|
+
}
|
|
173
|
+
data[key] = new JSONTag.Link(id)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
}
|
|
178
|
+
return data
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
let seen = new WeakMap()
|
|
182
|
+
function deProxy(o) {
|
|
183
|
+
if (!o) {
|
|
184
|
+
return o
|
|
185
|
+
}
|
|
186
|
+
if (typeof o !== 'object') {
|
|
187
|
+
return o
|
|
188
|
+
}
|
|
189
|
+
if (seen.has(o)) {
|
|
190
|
+
return seen.get(o)
|
|
191
|
+
}
|
|
192
|
+
let result
|
|
193
|
+
if (Array.isArray(o)) {
|
|
194
|
+
result = o.map(deProxy)
|
|
195
|
+
} else if (JSONTag.isNull(o)) {
|
|
196
|
+
return o
|
|
197
|
+
} else if (JSONTag.getType(o)==='object' && o[source]) {
|
|
198
|
+
result = JSONTag.clone(o[source])
|
|
199
|
+
seen.set(o, result)
|
|
200
|
+
Object.entries(o[source]).forEach(([i,v]) => {
|
|
201
|
+
result[i] = deProxy(v)
|
|
202
|
+
})
|
|
203
|
+
} else {
|
|
204
|
+
seen.set(o, o)
|
|
205
|
+
result = o
|
|
206
|
+
}
|
|
207
|
+
return result
|
|
208
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { parentPort } from 'node:worker_threads'
|
|
2
|
+
import tasks from './query-worker-module.mjs'
|
|
3
|
+
|
|
4
|
+
parentPort.on('message', async task => {
|
|
5
|
+
let result
|
|
6
|
+
if (tasks[task.name]) {
|
|
7
|
+
result = await tasks[task.name].call(tasks, task)
|
|
8
|
+
} else {
|
|
9
|
+
result = new Error('Unknown task '+task.name)
|
|
10
|
+
}
|
|
11
|
+
parentPort.postMessage(result)
|
|
12
|
+
})
|