geonix 1.8.20 → 1.10.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "geonix",
3
- "version": "1.8.20",
3
+ "version": "1.10.0",
4
4
  "type": "module",
5
5
  "description": "",
6
6
  "bin": {
package/src/Service.js CHANGED
@@ -32,11 +32,14 @@ export class Service {
32
32
 
33
33
  }
34
34
 
35
- // ---------------------------------------------------------------------------------------------
35
+ // ---------------------------------------------------------------------------------------------
36
36
 
37
37
  #me = {}
38
+ #options = {}
38
39
 
39
40
  async #start(options = {}) {
41
+ this.#options = options
42
+
40
43
  await webserver.waitUntilReady()
41
44
  await connection.waitUntilReady()
42
45
 
@@ -67,6 +70,12 @@ export class Service {
67
70
  a: webserver.getAddresses().map(address => `${address}:${webserver.getPort()}`)
68
71
  }
69
72
 
73
+ // check if method takes context as first argument
74
+ for (let methodName of this.#me.m) {
75
+ const method = this[methodName]
76
+ method.takesContext = method.toString()?.match(/\((?<args>.*)\)/)?.groups?.args.startsWith('$')
77
+ }
78
+
70
79
  this.#beacon()
71
80
  this.#queueListener()
72
81
  this.#directListener()
@@ -145,6 +154,11 @@ export class Service {
145
154
 
146
155
  let handlers = (Array.isArray(this[endpoint]) ? this[endpoint] : [this[endpoint]])
147
156
 
157
+ if (Array.isArray(this.#options?.handlers?.before))
158
+ handlers = [...this.#options?.handlers?.before, ...handlers]
159
+ if (Array.isArray(this.#options?.handlers?.after))
160
+ handlers = [...handlers, ...this.#options?.handlers?.after]
161
+
148
162
  for (let n = 0; n < handlers.length; n++)
149
163
  handlers[n] = handlers[n].bind(this)
150
164
 
@@ -185,8 +199,11 @@ export class Service {
185
199
  return respond({ e: `unknown method (${this.#me.n}.${methodName})` })
186
200
 
187
201
  try {
188
- const methodContext = { context, caller, me: this.#me }
189
- respond({ r: await method.apply(OverlayObject(this, methodContext), _args) })
202
+ // inject context as first argument
203
+ if (method.takesContext)
204
+ _args = [OverlayObject(context, { caller, me: this.#me }), ..._args]
205
+
206
+ respond({ r: await method.apply(this, _args) })
190
207
  } catch (e) {
191
208
  respond({ e: `${EOL}${ERROR_BEGIN_DELIMITER} ${this.#me.n}${EOL}${e.stack}${EOL}${ERROR_END_DELIMITER}` })
192
209
  }
package/test/.env DELETED
@@ -1 +0,0 @@
1
- TRANSPORT=nats://phobos.tria.hr:4222
@@ -1,60 +0,0 @@
1
- import { Service, Remote } from 'geonix'
2
-
3
- const calc = Remote('Calculator')
4
- const tp = Remote('TimeProvider')
5
-
6
- class Logger {
7
-
8
- constructor(prefix) {
9
- this.prefix = prefix
10
- }
11
-
12
- log(...args) {
13
- console.log(`${new Date().toISOString()}|${this.prefix}|`, ...args)
14
- }
15
- }
16
-
17
- class BaseService extends Service {
18
-
19
- logger = new Logger(this.constructor.name)
20
-
21
- }
22
-
23
-
24
- class CalculatorRepository {
25
-
26
- constructor(service) {
27
- this.logger = service.logger
28
- }
29
-
30
- async getCurrentTime() {
31
- this.logger.log('getCurrentTime')
32
- return await Remote('TimeProvider').now()
33
- }
34
-
35
- }
36
-
37
- class Calculator extends BaseService {
38
-
39
- repo = new CalculatorRepository(this)
40
-
41
- async onStart() {
42
- this.logger.log('current time =', await this.repo.getCurrentTime())
43
- }
44
-
45
- thisHere() {
46
-
47
- }
48
-
49
- }
50
-
51
- class TimeProvider extends BaseService {
52
-
53
- now() {
54
- return new Date().toISOString()
55
- }
56
-
57
- }
58
-
59
- Calculator.start()
60
- TimeProvider.start()
package/test/package.json DELETED
@@ -1,18 +0,0 @@
1
- {
2
- "name": "test",
3
- "version": "1.0.0",
4
- "description": "",
5
- "type": "module",
6
- "main": "stream.js",
7
- "scripts": {
8
- "test": "echo \"Error: no test specified\" && exit 1"
9
- },
10
- "keywords": [],
11
- "author": "",
12
- "license": "ISC",
13
- "dependencies": {
14
- "dotenv": "^16.3.1",
15
- "geonix": "file:..",
16
- "nats": "^2.16.0"
17
- }
18
- }
package/test/private.js DELETED
@@ -1,31 +0,0 @@
1
- export const OverlayObject = (object, overlay) => {
2
- return new Proxy(object, {
3
- get: (t, p) => overlay[p] !== undefined ? overlay[p] : t[p]
4
- }
5
- )
6
- }
7
-
8
- class Test {
9
-
10
- #me = { works: true }
11
-
12
- get me() { return this.#me }
13
-
14
- external() {
15
- return this.me
16
- }
17
-
18
- call(method) {
19
- try {
20
- const methodContext = { context: 'this is context value' }
21
- const $context = OverlayObject(this, methodContext)
22
- return instance[method].apply($context)
23
- } catch (e) {
24
- }
25
- }
26
-
27
- }
28
-
29
- const instance = new Test()
30
-
31
- console.log(instance.call('external'))
@@ -1,29 +0,0 @@
1
- import { Service, Remote, registry } from '../exports.js'
2
- import { sleep } from '../src/Util.js'
3
-
4
- class First extends Service {
5
-
6
- getTime() {
7
- return new Date().toISOString()
8
- }
9
-
10
- }
11
-
12
- class Second extends Service {
13
-
14
- first = Remote('First')
15
-
16
- async onStart() {
17
- while (true) {
18
- console.clear()
19
- console.log('Time =', await this.first.getTime())
20
- console.log('REGISTRY =', registry.getEntries())
21
-
22
- await sleep(1000)
23
- }
24
- }
25
-
26
- }
27
-
28
- First.start({ port: 30001 })
29
- Second.start({ port: 30002 })
package/test/stream.js DELETED
@@ -1,38 +0,0 @@
1
- import { randomBytes } from 'node:crypto'
2
- import { Stream, getReadable, connection } from 'geonix'
3
- import { createWriteStream, readFileSync } from 'node:fs'
4
- import { createHash } from 'node:crypto'
5
- import { pipeline } from 'node:stream/promises'
6
-
7
- await connection.waitUntilReady()
8
-
9
- const hash = data => createHash('sha512').update(data).digest('base64')
10
-
11
- const PAYLOAD_SIZE = 1024 * 1024 * 10
12
- const TEMP_FILE = '/tmp/geonix.stream_test'
13
-
14
- console.time('test')
15
- try {
16
- const payload = randomBytes(PAYLOAD_SIZE)
17
- const sourceHash = hash(payload)
18
-
19
- const source = await getReadable(Stream(payload))
20
- const dest = createWriteStream(TEMP_FILE)
21
-
22
- await pipeline(source, dest)
23
-
24
- const check = readFileSync(TEMP_FILE)
25
- const destHash = hash(check)
26
-
27
- if (sourceHash == destHash) {
28
- console.log('MATCH')
29
- } else {
30
- console.error('Destination does not match the source!')
31
- console.log(payload)
32
- console.log(check)
33
- }
34
- } catch (e) {
35
- console.error(e)
36
- } finally {
37
- console.timeEnd('test')
38
- }
package/test/stream2.js DELETED
@@ -1,42 +0,0 @@
1
- import 'dotenv/config'
2
- import { randomBytes } from 'node:crypto'
3
- import { Stream, Remote, getReadable, connection, Service, streamToBuffer } from 'geonix'
4
- import { createWriteStream, readFileSync } from 'node:fs'
5
- import { createHash } from 'node:crypto'
6
- import { pipeline } from 'node:stream/promises'
7
-
8
- const hash = data => createHash('sha256').update(data).digest('base64')
9
- const self = Remote('StreamTest')
10
-
11
- class StreamTest extends Service {
12
-
13
- async onStart() {
14
- const perform = async (n) => {
15
- const fileName = `${n}.random`
16
- const { checksum, stream } = await self.readFile(fileName)
17
- const data = await streamToBuffer(stream)
18
- const verification = hash(data)
19
-
20
- console.log(`${fileName} - ${data.length} bytes - ${checksum === verification}`)
21
- }
22
-
23
- const jobs = []
24
- for (let n = 0; n < 1024; n++)
25
- jobs.push(perform(n))
26
-
27
- await Promise.all(jobs)
28
-
29
- console.log('done')
30
- }
31
-
32
- async readFile(fileName, size = 1024 * Math.round(Math.random() * 1024)) {
33
- const bytes = randomBytes(size)
34
- const checksum = hash(bytes)
35
-
36
- return { checksum, stream: Stream(bytes) }
37
- }
38
-
39
-
40
- }
41
-
42
- StreamTest.start()