@muze-nl/simplystore 0.4.7 → 0.5.0

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.
@@ -0,0 +1,70 @@
1
+ const httpStatusCodes = {
2
+ '100': 'Continue',
3
+ '101': 'Switching Protocols',
4
+ '102': 'Processing',
5
+ '103': 'Early Hints',
6
+ '200': 'OK',
7
+ '201': 'Created',
8
+ '200': 'OK',
9
+ '201': 'Created',
10
+ '202': 'Accepted',
11
+ '203': 'Non-Authoritative Information',
12
+ '204': 'No Content',
13
+ '205': 'Reset Content',
14
+ '206': 'Partial Content',
15
+ '207': 'Multi-Status',
16
+ '208': 'Already Reported',
17
+ '226': 'IM Used',
18
+ '300': 'Multiple Choices',
19
+ '301': 'Moved Permanently',
20
+ '302': 'Found',
21
+ '303': 'See Other',
22
+ '304': 'Not Modified',
23
+ '305': 'Use Proxy',
24
+ '306': '(Unused)',
25
+ '307': 'Temporary Redirect',
26
+ '308': 'Permanent Redirect (experimental)',
27
+ '400': 'Bad Request',
28
+ '401': 'Unauthorized',
29
+ '402': 'Payment Required',
30
+ '403': 'Forbidden',
31
+ '404': 'Not Found',
32
+ '405': 'Method Not Allowed',
33
+ '406': 'Not Acceptable',
34
+ '407': 'Proxy Authentication Required',
35
+ '408': 'Request Timeout',
36
+ '409': 'Conflict',
37
+ '410': 'Gone',
38
+ '411': 'Length Required',
39
+ '412': 'Precondition Failed',
40
+ '413': 'Request Entity Too Large',
41
+ '414': 'Request-URI Too Long',
42
+ '415': 'Unsupported Media Type',
43
+ '416': 'Requested Range Not Satisfiable',
44
+ '417': 'Expectation Failed',
45
+ '418': 'I\'m a teapot (RFC 2324)',
46
+ '420': 'Enhance Your Calm (Twitter)',
47
+ '422': 'Unprocessable Entity (WebDAV)',
48
+ '423': 'Locked (WebDAV)',
49
+ '424': 'Failed Dependency (WebDAV)',
50
+ '425': 'Reserved for WebDAV',
51
+ '426': 'Upgrade Required',
52
+ '428': 'Precondition Required',
53
+ '429': 'Too Many Requests',
54
+ '431': 'Request Header Fields Too Large',
55
+ '451': 'Unavailable For Legal Reasons',
56
+ '500': 'Internal Server Error',
57
+ '501': 'Not Implemented',
58
+ '502': 'Bad Gateway',
59
+ '503': 'Service Unavailable',
60
+ '504': 'Gateway Timeout',
61
+ '505': 'HTTP Version Not Supported',
62
+ '506': 'Variant Also Negotiates (Experimental)',
63
+ '507': 'Insufficient Storage (WebDAV)',
64
+ '508': 'Loop Detected (WebDAV)',
65
+ '509': 'Bandwidth Limit Exceeded (Apache)',
66
+ '510': 'Not Extended',
67
+ '511': 'Network Authentication Required',
68
+ }
69
+
70
+ export default httpStatusCodes
@@ -0,0 +1,6 @@
1
+ export const source = Symbol('source')
2
+ export const isProxy = Symbol('isProxy')
3
+ export const getBuffer = Symbol('getBuffer')
4
+ export const getIndex = Symbol('getIndex')
5
+ export const isChanged = Symbol('isChanged')
6
+ export const getString = Symbol('getString')
package/src/util.mjs CHANGED
@@ -33,14 +33,14 @@ export function joinArgs(args) {
33
33
  * @return {void}
34
34
  */
35
35
  export async function appendFile(filename, data) {
36
- console.log('appending command')
37
36
  let handle;
38
37
  try {
39
- handle = await fs.open(filename, 'a')
38
+ handle = await fs.open(filename, 'a+')
40
39
  await handle.appendFile(data+"\n")
41
40
  await handle.datasync()
42
41
  return true
43
42
  } finally {
44
43
  await handle.close()
45
44
  }
46
- }
45
+ }
46
+
@@ -0,0 +1,99 @@
1
+ import { AsyncResource } from 'async_hooks'
2
+ import { EventEmitter } from 'events'
3
+ import path from 'path'
4
+ import { Worker } from 'worker_threads'
5
+
6
+ const kTaskInfo = Symbol('kTaskInfo');
7
+ const kWorkerFreedEvent = Symbol('kWorkerFreedEvent');
8
+
9
+ class WorkerPoolTaskInfo extends AsyncResource {
10
+ constructor(callback) {
11
+ super('WorkerPoolTaskInfo');
12
+ this.callback = callback;
13
+ }
14
+
15
+ done(err, result) {
16
+ this.runInAsyncScope(this.callback, null, err, result);
17
+ this.emitDestroy(); // `TaskInfo`s are used only once.
18
+ }
19
+ }
20
+
21
+ //@TODO: only create new workers when needed, not immediately
22
+ //@TODO: allow initialization of newly created workers
23
+
24
+ export default class WorkerPool extends EventEmitter {
25
+ constructor(numThreads, workerFile, initTask) {
26
+ super()
27
+ this.numThreads = numThreads
28
+ this.workerFile = workerFile
29
+ this.initTask = initTask
30
+ this.workers = []
31
+ this.freeWorkers = []
32
+
33
+ for (let i = 0; i < numThreads; i++)
34
+ this.addNewWorker();
35
+ }
36
+
37
+ addNewWorker() {
38
+ const worker = new Worker(path.resolve(this.workerFile));
39
+ worker.on('message', (result) => {
40
+ // In case of success: Call the callback that was passed to `runTask`,
41
+ // remove the `TaskInfo` associated with the Worker, and mark it as free
42
+ // again.
43
+ if (worker[kTaskInfo]) {
44
+ worker[kTaskInfo].done(null, result);
45
+ worker[kTaskInfo] = null;
46
+ }
47
+ this.freeWorkers.push(worker);
48
+ this.emit(kWorkerFreedEvent);
49
+ });
50
+ worker.on('error', (err) => {
51
+ // In case of an uncaught exception: Call the callback that was passed to
52
+ // `runTask` with the error.
53
+ if (worker[kTaskInfo])
54
+ worker[kTaskInfo].done(err, null);
55
+ else
56
+ this.emit('error', err);
57
+ // Remove the worker from the list and start a new Worker to replace the
58
+ // current one.
59
+ this.workers.splice(this.workers.indexOf(worker), 1);
60
+ this.addNewWorker();
61
+ });
62
+ this.workers.push(worker);
63
+ worker.postMessage(this.initTask);
64
+ }
65
+
66
+ async run(name, req) {
67
+ return new Promise((resolve, reject) => {
68
+ this.runTask({name,req}, (error, result) => {
69
+ if (error) {
70
+ return reject(error)
71
+ }
72
+ return resolve(result)
73
+ })
74
+ })
75
+ }
76
+
77
+ runTask(task, callback) {
78
+ if (this.freeWorkers.length === 0) {
79
+ // No free threads, wait until a worker thread becomes free.
80
+ console.log('no free worker.. waiting')
81
+ this.once(kWorkerFreedEvent, () => this.runTask(task, callback));
82
+ return;
83
+ }
84
+ const worker = this.freeWorkers.pop();
85
+ worker[kTaskInfo] = new WorkerPoolTaskInfo(callback);
86
+ worker.postMessage(task);
87
+ }
88
+
89
+ memoryUsage() {
90
+ for (let worker of this.freeWorkers) {
91
+ worker[kTaskInfo] = new WorkerPoolTaskInfo((result) => {})
92
+ worker.postMessage({name:'memoryUsage'})
93
+ }
94
+ }
95
+
96
+ close() {
97
+ for (const worker of this.workers) worker.terminate();
98
+ }
99
+ }
package/data.jsontag DELETED
@@ -1,20 +0,0 @@
1
- {
2
- "persons": [
3
- <object id="john" class="Person">{
4
- "name": "John",
5
- "lastName": "Doe",
6
- "dob": <date>"1972-09-20",
7
- "foaf": [
8
- <link>"jane"
9
- ]
10
- },
11
- <object id="jane" class="Person">{
12
- "name": "Jane",
13
- "lastName": "Doe",
14
- "dob": <date>"1986-01-01",
15
- "foaf": [
16
- <link>"john"
17
- ]
18
- }
19
- ]
20
- }
package/src/share.mjs DELETED
@@ -1,142 +0,0 @@
1
- import JSONTag from '@muze-nl/jsontag'
2
-
3
- const handler = function(root, index, buffer)
4
- {
5
- return {
6
- get(target, key, receiver)
7
- {
8
- let keyNumber = index.key[key]
9
- if (root[keyNumber]) {
10
- let keyStart = root[keyNumber].s + root.s
11
- let keyEnd = root[keyNumber].e + root.s
12
- subobjecten hoeven niet geparsed...
13
- if (root[keyNumber].c) {
14
- // object
15
- return new jsontagProxy(root[keyNumber], index, buffer)
16
- }
17
- return JSON.parse(buffer.slice(keyStart,keyEnd))
18
- }
19
- }
20
-
21
- has(target, key)
22
- {
23
- let keyNumber = index.key[key]
24
- return typeof root[keyNumber] !== 'undefined'
25
- }
26
-
27
- ownKeys(target)
28
- {
29
- return root.c.map(n => index.reverse[n])
30
- }
31
- }
32
- }
33
-
34
- export class jsontagProxy extends proxy
35
- {
36
- constructor(root, index, buffer)
37
- {
38
- super({}, handler(root, index, buffer))
39
- }
40
-
41
- }
42
-
43
- export default function share(data)
44
- {
45
- let jsontag = JSONTag.stringify(data)
46
- let buffer = new SharedArrayBuffer(jsontag.length)
47
- let dv = new DataView(buffer)
48
- let encode = new TextEncoder('utf-8')
49
- let root = {}
50
- let index = {
51
- key: {},
52
- reverse: [],
53
- types: {}
54
- }
55
- let current = 0
56
-
57
- function getKey(key) {
58
- let l;
59
- if (typeof index.key[key] == 'undefined') {
60
- l = Object.keys(index.key)
61
- index.key[key] = l
62
- index.reverse[l] = key
63
- }
64
- return index.key[key]
65
- }
66
-
67
- function getType(type) {
68
- if (typeof index.types[type] == 'undefined') {
69
- l = Object.keys(index.types);
70
- index.types[type] = l
71
- }
72
-
73
- }
74
-
75
- function store(container, key, value) {
76
- let l = getKey(key)
77
- container[l] = {
78
- s: current
79
- }
80
- container = container[l]
81
- let attributes = JSONTag.getAttributes(value)
82
- if (attributes) {
83
- container.a = {
84
- s: current,
85
- c: {}
86
- }
87
- attributes.forEach((v,k) => {
88
- let l = getKey(k)
89
- let t = getType('string')
90
- container.a.c[k] = {
91
- s: current,
92
- t
93
- }
94
- let v = JSON.stringify(value)
95
- let (r,w) = encoder.encodeInto(v, dv, current)
96
- current += w
97
- container.a.c[k].e = current
98
- })
99
- }
100
- let type = JSONTag.getType(node)
101
- let t = getType(type)
102
- container.t = t
103
- let v = JSON.stringify(value)
104
- let (r,w) = encoder.encodeInto(v, dv, current)
105
- current+= w
106
- container.e = current
107
- }
108
-
109
-
110
- function walk(node, parentKey, parent, save)
111
- {
112
- let type = JSONTag.getType(node)
113
- let t = getType(type)
114
- switch (type) {
115
- case 'array':
116
- save.s = current
117
- save.t = t
118
- save.c = []
119
- node.forEach((v,k) => walk(v, k, node, save.c))
120
- save.e = current
121
- break
122
- case 'object':
123
- save.s = current
124
- save.c = []
125
- save.t = t
126
- Object.entries(node).forEach((k,v) => walk(v, k, node, save.c))
127
- save.e = current
128
- break
129
- default:
130
- store(save, parentKey, node)
131
- break
132
- }
133
- }
134
-
135
- walk(data, null, null, root)
136
-
137
- return {
138
- root: new jsontagProxy(root, index, buffer),
139
- index,
140
- buffer
141
- }
142
- }
@@ -1,14 +0,0 @@
1
- import JSONTag from '@muze-nl/jsontag';
2
- import worker_threads from 'node:worker_threads';
3
- import * as queryWorker from './worker-query.mjs';
4
-
5
- async function initialize() {
6
- let meta = {}
7
- let dataspace = JSONTag.parse(worker_threads.workerData, null, meta)
8
- //console.log('starting')
9
- await queryWorker.initialize(dataspace,meta)
10
- //console.log('initialized')
11
- return queryWorker.runQuery
12
- }
13
-
14
- export default initialize()