@toa.io/userland 1.0.0-alpha.274 → 1.0.0-alpha.278

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/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [1.0.0-alpha.278](https://github.com/toa-io/toa/compare/v1.0.0-alpha.277...v1.0.0-alpha.278) (2026-09-03)
7
+
8
+ **Note:** Version bump only for package @toa.io/userland
9
+
10
+
11
+
12
+
13
+
14
+ # [1.0.0-alpha.277](https://github.com/toa-io/toa/compare/v1.0.0-alpha.276...v1.0.0-alpha.277) (2026-09-03)
15
+
16
+ ### Bug Fixes
17
+
18
+ * settle what the module loader made asynchronous ([d4ab9df](https://github.com/toa-io/toa/commit/d4ab9dfb09e382da311dba08f52214e7645f4a6c))
19
+ * what the loader resolves, and what it will not ([1b8a02f](https://github.com/toa-io/toa/commit/1b8a02ff0a5e0f18ee62e3f71bc81116f86f9af1))
20
+
21
+
6
22
  # [1.0.0-alpha.274](https://github.com/toa-io/toa/compare/v1.0.0-alpha.273...v1.0.0-alpha.274) (2026-09-02)
7
23
 
8
24
 
@@ -1,7 +1,3 @@
1
- 'use strict'
2
-
3
- async function computation (_, context) {
1
+ export async function computation (_, context) {
4
2
  return context.state.value
5
3
  }
6
-
7
- exports.computation = computation
@@ -1,7 +1,3 @@
1
- 'use strict'
2
-
3
- async function computation (key, context) {
1
+ export async function computation (key, context) {
4
2
  return context.state.values.get(key)
5
3
  }
6
-
7
- exports.computation = computation
@@ -1,6 +1,4 @@
1
- 'use strict'
2
-
3
- class Computation {
1
+ export class Computation {
4
2
  #context
5
3
 
6
4
  async mount (context) {
@@ -11,5 +9,3 @@ class Computation {
11
9
  return this.#context.configuration.signal
12
10
  }
13
11
  }
14
-
15
- exports.Computation = Computation
@@ -1,7 +1,3 @@
1
- 'use strict'
2
-
3
- async function computation (input) {
1
+ export async function computation (input) {
4
2
  return input.a + input.b
5
3
  }
6
-
7
- exports.computation = computation
@@ -1,6 +1,4 @@
1
- 'use strict'
2
-
3
- async function computation (input, context) {
1
+ export async function computation (input, context) {
4
2
  let value = input.value
5
3
 
6
4
  for (let i = 0; i < input.times; i++) {
@@ -9,5 +7,3 @@ async function computation (input, context) {
9
7
 
10
8
  return value
11
9
  }
12
-
13
- exports.computation = computation
@@ -1,10 +1,6 @@
1
- 'use strict'
2
-
3
- async function computation (input, context) {
1
+ export async function computation (input, context) {
4
2
  const request = { input }
5
3
 
6
4
  // noinspection JSUnresolvedVariable
7
5
  return context.remote.math.calculations.add(request)
8
6
  }
9
-
10
- exports.computation = computation
@@ -1,6 +1,4 @@
1
- 'use strict'
2
-
3
- async function computation (input, context) {
1
+ export async function computation (input, context) {
4
2
  const criteria = `material==${input}`
5
3
  const query = { criteria, limit }
6
4
 
@@ -9,5 +7,3 @@ async function computation (input, context) {
9
7
  }
10
8
 
11
9
  const limit = 10
12
-
13
- exports.computation = computation
@@ -1,8 +1,4 @@
1
- 'use strict'
2
-
3
- const request = async (payload) => ({
1
+ export const request = async (payload) => ({
4
2
  input: { booked: true },
5
3
  query: { id: payload.pot }
6
4
  })
7
-
8
- exports.request = request
@@ -1,6 +1,4 @@
1
- 'use strict'
2
-
3
- async function computation (_, context) {
1
+ export async function computation (_, context) {
4
2
  const response = await context.fetch('http://api.example.com/path/to/resource')
5
3
  const type = response.headers.get('content-type')
6
4
 
@@ -11,5 +9,3 @@ async function computation (_, context) {
11
9
  }
12
10
 
13
11
  const ERR_UNSUPPORTED_MEDIA_TYPE = new Error('UNSUPPORTED_MEDIA_TYPE')
14
-
15
- exports.computation = computation
@@ -1,15 +1,18 @@
1
- 'use strict'
1
+ import { it, before, after } from 'node:test'
2
+ import assert from 'node:assert/strict'
2
3
 
3
- const { resolve } = require('node:path')
4
- const { exceptions: { RequestContractException } } = require('@toa.io/core')
5
- const stage = require('@toa.io/userland/stage')
4
+ import { resolve } from 'node:path'
5
+ import { exceptions } from '@toa.io/core'
6
+ import * as stage from '@toa.io/userland/stage'
6
7
 
7
- const root = resolve(__dirname, '../components')
8
+ const { RequestContractException } = exceptions
9
+
10
+ const root = resolve(import.meta.dirname, '../components')
8
11
 
9
12
  let echo
10
13
  let math
11
14
 
12
- beforeAll(async () => {
15
+ before(async () => {
13
16
  process.env.TOA_DEV = '1'
14
17
  process.env.TOA_CONFIGURATION_DEFAULT_ECHO = '{}'
15
18
  process.env.TOA_CONFIGURATION_TEA_POTS = '{}'
@@ -22,7 +25,7 @@ beforeAll(async () => {
22
25
  math = await stage.remote('math.calculations')
23
26
  })
24
27
 
25
- afterAll(async () => {
28
+ after(async () => {
26
29
  await stage.shutdown()
27
30
 
28
31
  delete process.env.TOA_DEV
@@ -31,13 +34,12 @@ afterAll(async () => {
31
34
  it('should call endpoint', async () => {
32
35
  const reply = await echo.invoke('signal', {})
33
36
 
34
- expect(reply).toStrictEqual('quack')
37
+ assert.deepStrictEqual(reply, 'quack')
35
38
  })
36
39
 
37
40
  it('should throw on invalid input', async () => {
38
41
  const a = 'not a number'
39
42
  const b = 'neither'
40
43
 
41
- await expect(math.invoke('add', { input: { a, b } }))
42
- .rejects.toBeInstanceOf(RequestContractException)
44
+ await assert.rejects(math.invoke('add', { input: { a, b } }), (error) => { assert.ok(error instanceof RequestContractException); return true })
43
45
  })
@@ -1,18 +1,19 @@
1
- 'use strict'
1
+ import { it, before, after } from 'node:test'
2
+ import assert from 'node:assert/strict'
2
3
 
3
- const { resolve } = require('node:path')
4
- const boot = require('@toa.io/boot')
5
- const { Connector, Locator } = require('@toa.io/core')
6
- const { timeout } = require('@toa.io/generic')
7
- const stage = require('@toa.io/userland/stage')
4
+ import { resolve } from 'node:path'
5
+ import * as boot from '@toa.io/boot'
6
+ import { Connector, Locator } from '@toa.io/core'
7
+ import { timeout } from '@toa.io/generic'
8
+ import * as stage from '@toa.io/userland/stage'
8
9
 
9
- const root = resolve(__dirname, '../components')
10
+ const root = resolve(import.meta.dirname, '../components')
10
11
 
11
12
  let remote
12
13
  let emitter
13
14
  let consumer
14
15
 
15
- beforeAll(async () => {
16
+ before(async () => {
16
17
  process.env.TOA_DEV = '1'
17
18
  process.env.TOA_CONFIGURATION_TEA_POTS = '{}'
18
19
 
@@ -26,12 +27,12 @@ beforeAll(async () => {
26
27
  remote = await stage.remote('tea.pots')
27
28
 
28
29
  // what `store.orders` would emit, sent the way it would send it
29
- emitter = boot.bindings.emit(AMQP, new Locator('orders', 'store'), 'created')
30
+ emitter = await boot.bindings.emit(AMQP, new Locator('orders', 'store'), 'created')
30
31
 
31
32
  await emitter.connect()
32
33
  })
33
34
 
34
- afterAll(async () => {
35
+ after(async () => {
35
36
  await consumer?.disconnect()
36
37
  await emitter.disconnect()
37
38
  await stage.shutdown()
@@ -59,7 +60,7 @@ it('should receive event', async () => {
59
60
  reply = await remote.invoke('observe', request)
60
61
  } while (reply.booked !== true && Date.now() < deadline)
61
62
 
62
- expect(reply.booked).toStrictEqual(true)
63
+ assert.deepStrictEqual(reply.booked, true)
63
64
  })
64
65
 
65
66
  it('should emit event', async () => {
@@ -76,7 +77,7 @@ it('should emit event', async () => {
76
77
 
77
78
  const payload = await received
78
79
 
79
- expect(payload.material).toStrictEqual(material)
80
+ assert.deepStrictEqual(payload.material, material)
80
81
  })
81
82
 
82
83
  /** What the event consumer hands deliveries to. */
@@ -1,14 +1,15 @@
1
- 'use strict'
1
+ import { it, before, after } from 'node:test'
2
+ import assert from 'node:assert/strict'
2
3
 
3
- const { resolve } = require('node:path')
4
- const stage = require('@toa.io/userland/stage')
4
+ import { resolve } from 'node:path'
5
+ import * as stage from '@toa.io/userland/stage'
5
6
 
6
- const root = resolve(__dirname, '../components')
7
+ const root = resolve(import.meta.dirname, '../components')
7
8
 
8
9
  /** @type {toa.core.Component} */
9
10
  let component
10
11
 
11
- beforeAll(async () => {
12
+ before(async () => {
12
13
  process.env.TOA_DEV = '1'
13
14
  process.env.TOA_CONFIGURATION_DEFAULT_ECHO = '{}'
14
15
  process.env.TOA_CONFIGURATION_TEA_POTS = '{}'
@@ -18,7 +19,7 @@ beforeAll(async () => {
18
19
  component = await stage.component(path)
19
20
  })
20
21
 
21
- afterAll(async () => {
22
+ after(async () => {
22
23
  await stage.shutdown()
23
24
 
24
25
  delete process.env.TOA_DEV
@@ -30,6 +31,6 @@ it('should invoke', async () => {
30
31
 
31
32
  const reply = await component.invoke('add', { input: { a, b } })
32
33
 
33
- expect(reply.exception).toBeUndefined()
34
- expect(reply.output).toStrictEqual(a + b)
34
+ assert.strictEqual(reply.exception, undefined)
35
+ assert.deepStrictEqual(reply.output, a + b)
35
36
  })
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@toa.io/userland",
3
- "version": "1.0.0-alpha.274",
3
+ "version": "1.0.0-alpha.278",
4
+ "type": "module",
4
5
  "description": "Toa development kit",
5
6
  "homepage": "https://toa.io",
6
7
  "author": {
@@ -22,15 +23,20 @@
22
23
  "access": "public"
23
24
  },
24
25
  "main": "src/index.js",
26
+ "exports": {
27
+ ".": "./src/index.js",
28
+ "./stage": "./stage/src/index.js",
29
+ "./package.json": "./package.json"
30
+ },
25
31
  "types": "types/index.d.ts",
26
32
  "dependencies": {
27
- "@toa.io/boot": "1.0.0-alpha.274",
28
- "@toa.io/core": "1.0.0-alpha.273",
29
- "@toa.io/generic": "1.0.0-alpha.273",
30
- "@toa.io/norm": "1.0.0-alpha.274",
31
- "@toa.io/schemas": "1.0.0-alpha.274",
33
+ "@toa.io/boot": "1.0.0-alpha.278",
34
+ "@toa.io/core": "1.0.0-alpha.278",
35
+ "@toa.io/generic": "1.0.0-alpha.278",
36
+ "@toa.io/norm": "1.0.0-alpha.278",
37
+ "@toa.io/schemas": "1.0.0-alpha.278",
32
38
  "@toa.io/storages.null": "0.22.0",
33
- "js-yaml": "4.3.1"
39
+ "js-yaml": "5.4.1"
34
40
  },
35
- "gitHead": "7df32eb2872155c45681c299036b1efbeefd6518"
41
+ "gitHead": "5872815748eed8021ea99d7beca1602f4fc5c958"
36
42
  }
@@ -1,4 +1,5 @@
1
1
  {
2
+ "type": "module",
2
3
  "private": true,
3
4
  "main": "src/index.js",
4
5
  "types": "types/index.d.ts"
@@ -1,10 +1,8 @@
1
- 'use strict'
2
-
3
- const boot = require('@toa.io/boot')
4
- const { state } = require('./state')
1
+ import * as boot from '@toa.io/boot'
2
+ import { state } from './state.js'
5
3
 
6
4
  /** @type {toa.stage.Component} */
7
- const component = async (path, options) => {
5
+ export const component = async (path, options) => {
8
6
  const manifest = await boot.manifest(path, options)
9
7
  const component = await boot.component(manifest)
10
8
 
@@ -14,5 +12,3 @@ const component = async (path, options) => {
14
12
 
15
13
  return component
16
14
  }
17
-
18
- exports.component = component
@@ -1,15 +1,11 @@
1
- 'use strict'
2
-
3
- const boot = require('@toa.io/boot')
4
- const { state } = require('./state')
1
+ import * as boot from '@toa.io/boot'
2
+ import { state } from './state.js'
5
3
 
6
4
  /** @type {toa.stage.Composition} */
7
- const composition = async (paths, options) => {
5
+ export const composition = async (paths, options) => {
8
6
  const composition = await boot.composition(paths, options)
9
7
 
10
8
  await composition.connect()
11
9
 
12
10
  state.compositions.push(composition)
13
11
  }
14
-
15
- exports.composition = composition
@@ -1,16 +1,8 @@
1
- 'use strict'
1
+ import { manifest } from './manifest.js'
2
+ import { component } from './component.js'
3
+ import { composition } from './composition.js'
4
+ import { service } from './service.js'
5
+ import { remote } from './remote.js'
6
+ import { shutdown } from './shutdown.js'
2
7
 
3
- const { manifest } = require('./manifest')
4
- const { component } = require('./component')
5
- const { composition } = require('./composition')
6
- const { service } = require('./service')
7
- const { remote } = require('./remote')
8
- const { shutdown } = require('./shutdown')
9
-
10
- exports.manifest = manifest
11
- exports.component = component
12
- exports.composition = composition
13
- exports.compose = composition
14
- exports.serve = service
15
- exports.remote = remote
16
- exports.shutdown = shutdown
8
+ export { manifest, component, composition, composition as compose, service as serve, remote, shutdown }
@@ -1,12 +1,8 @@
1
- 'use strict'
2
-
3
- const boot = require('@toa.io/boot')
1
+ import * as boot from '@toa.io/boot'
4
2
 
5
3
  /**
6
4
  * @type {toa.stage.Manifest}
7
5
  */
8
- const manifest = async (path) => {
6
+ export const manifest = async (path) => {
9
7
  return boot.manifest(path)
10
8
  }
11
-
12
- exports.manifest = manifest
@@ -1,12 +1,10 @@
1
- 'use strict'
1
+ import * as boot from '@toa.io/boot'
2
+ import { Locator } from '@toa.io/core'
2
3
 
3
- const boot = require('@toa.io/boot')
4
- const { Locator } = require('@toa.io/core')
5
-
6
- const { state } = require('./state')
4
+ import { state } from './state.js'
7
5
 
8
6
  /** @type {toa.stage.Remote} */
9
- const remote = async (id) => {
7
+ export const remote = async (id) => {
10
8
  const segments = id.split('.')
11
9
 
12
10
  if (segments.length === 1) segments.unshift('default')
@@ -28,5 +26,3 @@ const remote = async (id) => {
28
26
  * `unknown` on the application's map.
29
27
  */
30
28
  const SOURCE = { service: 'features' }
31
-
32
- exports.remote = remote
@@ -1,14 +1,17 @@
1
- 'use strict'
1
+ import { createRequire } from 'node:module'
2
+ import { pathToFileURL } from 'node:url'
3
+ import * as boot from '@toa.io/boot'
4
+ import { state } from './state.js'
5
+ import { shortcuts } from '@toa.io/norm'
2
6
 
3
- const boot = require('@toa.io/boot')
4
- const { state } = require('./state')
5
- const { shortcuts } = require('@toa.io/norm')
7
+ // a shortcut resolves to a package name, which is not a path
8
+ const require = createRequire(import.meta.url)
6
9
 
7
- const service = async (ref) => {
10
+ export const service = async (ref) => {
8
11
  const path = shortcuts.resolve(ref)
9
- const { Factory } = require(path)
12
+ const { Factory } = await import(pathToFileURL(require.resolve(path)).href)
10
13
  const factory = new Factory(boot)
11
- const service = factory.service()
14
+ const service = await factory.service()
12
15
 
13
16
  await service.connect()
14
17
 
@@ -16,5 +19,3 @@ const service = async (ref) => {
16
19
 
17
20
  return service
18
21
  }
19
-
20
- exports.service = service
@@ -1,9 +1,7 @@
1
- 'use strict'
2
-
3
- const { state } = require('./state')
1
+ import { state } from './state.js'
4
2
 
5
3
  /** @type {toa.stage.Shutdown} */
6
- const shutdown = async () => {
4
+ export const shutdown = async () => {
7
5
  const components = state.components.map((component) => component.disconnect())
8
6
  const compositions = state.compositions.map((composition) => composition.disconnect())
9
7
  const services = state.services.map((service) => service.disconnect())
@@ -14,5 +12,3 @@ const shutdown = async () => {
14
12
 
15
13
  state.reset()
16
14
  }
17
-
18
- exports.shutdown = shutdown
@@ -1,6 +1,4 @@
1
- 'use strict'
2
-
3
- const state = {}
1
+ export const state = {}
4
2
 
5
3
  const reset = () => {
6
4
  Object.assign(state, {
@@ -15,4 +13,3 @@ const reset = () => {
15
13
  reset()
16
14
 
17
15
  /** @type {toa.stage.State} */
18
- exports.state = state
@@ -1,16 +1,14 @@
1
- 'use strict'
1
+ import { mock } from 'node:test'
2
2
 
3
- const { generate } = require('randomstring')
3
+ import { generate } from 'randomstring'
4
4
 
5
5
  const connector = () => ({
6
- connect: jest.fn(),
7
- disconnect: jest.fn(),
8
- link: jest.fn()
6
+ connect: mock.fn(),
7
+ disconnect: mock.fn(),
8
+ link: mock.fn()
9
9
  })
10
10
 
11
- const manifest = jest.fn(async () => generate())
12
- const component = jest.fn(async () => connector())
13
- const composition = jest.fn(async () => connector())
14
- const remote = jest.fn(async () => connector())
15
-
16
- module.exports = { manifest, component, composition, remote }
11
+ export const manifest = mock.fn(async () => generate())
12
+ export const component = mock.fn(async () => connector())
13
+ export const composition = mock.fn(async () => connector())
14
+ export const remote = mock.fn(async () => connector())
@@ -1,25 +1,31 @@
1
- 'use strict'
1
+ import { it, mock as mocking } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import { isDeepStrictEqual } from 'node:util'
2
4
 
3
- const { generate } = require('randomstring')
5
+ import { generate } from 'randomstring'
6
+ import * as _boot from './boot.mock.js'
4
7
 
5
8
  const mock = {
6
- boot: require('./boot.mock')
9
+ boot: _boot
7
10
  }
8
11
 
9
- jest.mock('@toa.io/boot', () => mock.boot)
12
+ mocking.module('@toa.io/boot', { namedExports: mock.boot })
10
13
 
11
- const stage = require('../')
14
+ const stage = await import('../src/index.js')
12
15
 
13
16
  it('should be', () => {
14
- expect(stage.component).toBeDefined()
17
+ assert.notStrictEqual(stage.component, undefined)
15
18
  })
16
19
 
17
20
  it('should boot component', async () => {
18
21
  const path = generate()
19
22
  const component = await stage.component(path)
20
23
 
21
- expect(mock.boot.manifest.mock.calls[0][0]).toStrictEqual(path)
22
- expect(mock.boot.component).toHaveBeenCalledWith(await mock.boot.manifest.mock.results[0].value)
23
- expect(component).toStrictEqual(await mock.boot.component.mock.results[0].value)
24
- expect(component.connect).toHaveBeenCalled()
24
+ assert.deepStrictEqual(mock.boot.manifest.mock.calls[0].arguments[0], path)
25
+ const manifest = await mock.boot.manifest.mock.calls[0].result
26
+
27
+ assert.ok(mock.boot.component.mock.calls.some((call) =>
28
+ call.arguments.length === 1 && isDeepStrictEqual(call.arguments[0], manifest)))
29
+ assert.deepStrictEqual(component, await mock.boot.component.mock.calls[0].result)
30
+ assert.ok(component.connect.mock.callCount() > 0)
25
31
  })
@@ -1,27 +1,29 @@
1
- 'use strict'
1
+ import { it, mock as mocking } from 'node:test'
2
+ import assert from 'node:assert/strict'
2
3
 
3
- const { generate } = require('randomstring')
4
+ import { generate } from 'randomstring'
5
+ import * as _boot from './boot.mock.js'
4
6
 
5
7
  const mock = {
6
- boot: require('./boot.mock')
8
+ boot: _boot
7
9
  }
8
10
 
9
- jest.mock('@toa.io/boot', () => mock.boot)
11
+ mocking.module('@toa.io/boot', { namedExports: mock.boot })
10
12
 
11
- const stage = require('../')
13
+ const stage = await import('../src/index.js')
12
14
 
13
15
  const paths = [generate(), generate()]
14
16
 
15
17
  it('should be', () => {
16
- expect(stage.composition).toBeDefined()
18
+ assert.notStrictEqual(stage.composition, undefined)
17
19
  })
18
20
 
19
21
  it('should boot composition', async () => {
20
22
  await stage.composition(paths)
21
23
 
22
- expect(mock.boot.composition.mock.calls[0][0]).toStrictEqual(paths)
24
+ assert.deepStrictEqual(mock.boot.composition.mock.calls[0].arguments[0], paths)
23
25
 
24
- const composition = await mock.boot.composition.mock.results[0].value
26
+ const composition = await mock.boot.composition.mock.calls[0].result
25
27
 
26
- expect(composition.connect).toHaveBeenCalled()
28
+ assert.ok(composition.connect.mock.callCount() > 0)
27
29
  })
@@ -1,17 +1,20 @@
1
- 'use strict'
1
+ import { it, mock as mocking } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import { isDeepStrictEqual } from 'node:util'
2
4
 
3
- const { generate } = require('randomstring')
5
+ import { generate } from 'randomstring'
6
+ import * as _boot from './boot.mock.js'
4
7
 
5
8
  const mock = {
6
- boot: require('./boot.mock')
9
+ boot: _boot
7
10
  }
8
11
 
9
- jest.mock('@toa.io/boot', () => mock.boot)
12
+ mocking.module('@toa.io/boot', { namedExports: mock.boot })
10
13
 
11
- const stage = require('../')
14
+ const stage = await import('../src/index.js')
12
15
 
13
16
  it('should be', () => {
14
- expect(stage.manifest).toBeDefined()
17
+ assert.notStrictEqual(stage.manifest, undefined)
15
18
  })
16
19
 
17
20
  it('should boot manifest', async () => {
@@ -19,6 +22,6 @@ it('should boot manifest', async () => {
19
22
 
20
23
  const manifest = await stage.manifest(path)
21
24
 
22
- expect(mock.boot.manifest).toHaveBeenCalledWith(path)
23
- expect(manifest).toStrictEqual(await mock.boot.manifest.mock.results[0].value)
25
+ assert.ok(mock.boot.manifest.mock.calls.some((call) => call.arguments.length === 1 && isDeepStrictEqual(call.arguments[0], path)))
26
+ assert.deepStrictEqual(manifest, await mock.boot.manifest.mock.calls[0].result)
24
27
  })
@@ -1,17 +1,19 @@
1
- 'use strict'
1
+ import { it, mock as mocking } from 'node:test'
2
+ import assert from 'node:assert/strict'
2
3
 
3
- const { generate } = require('randomstring')
4
+ import { generate } from 'randomstring'
5
+ import * as _boot from './boot.mock.js'
4
6
 
5
7
  const mock = {
6
- boot: require('./boot.mock')
8
+ boot: _boot
7
9
  }
8
10
 
9
- jest.mock('@toa.io/boot', () => mock.boot)
11
+ mocking.module('@toa.io/boot', { namedExports: mock.boot })
10
12
 
11
- const stage = require('../')
13
+ const stage = await import('../src/index.js')
12
14
 
13
15
  it('should be', () => {
14
- expect(stage.remote).toBeDefined()
16
+ assert.notStrictEqual(stage.remote, undefined)
15
17
  })
16
18
 
17
19
  it('should connect remote', async () => {
@@ -21,12 +23,12 @@ it('should connect remote', async () => {
21
23
 
22
24
  const remote = await stage.remote(id)
23
25
 
24
- expect(mock.boot.remote).toHaveBeenCalled()
25
- expect(remote).toStrictEqual(await mock.boot.remote.mock.results[0].value)
26
- expect(remote.connect).toHaveBeenCalled()
26
+ assert.ok(mock.boot.remote.mock.callCount() > 0)
27
+ assert.deepStrictEqual(remote, await mock.boot.remote.mock.calls[0].result)
28
+ assert.ok(remote.connect.mock.callCount() > 0)
27
29
 
28
- const locator = mock.boot.remote.mock.calls[0][0]
30
+ const locator = mock.boot.remote.mock.calls[0].arguments[0]
29
31
 
30
- expect(locator).toBeDefined()
31
- expect(locator).toMatchObject({ name, namespace })
32
+ assert.notStrictEqual(locator, undefined)
33
+ assert.partialDeepStrictEqual(locator, { name, namespace })
32
34
  })
@@ -1,24 +1,27 @@
1
- 'use strict'
1
+ import { it, beforeEach, mock as mocking } from 'node:test'
2
+ import assert from 'node:assert/strict'
2
3
 
3
- const { generate } = require('randomstring')
4
+ import { generate } from 'randomstring'
5
+ import * as _boot from './boot.mock.js'
6
+ import * as _state from './state.mock.js'
4
7
 
5
8
  const mock = {
6
- boot: require('./boot.mock'),
7
- state: require('./state.mock')
9
+ boot: _boot,
10
+ state: _state
8
11
  }
9
12
 
10
- jest.mock('@toa.io/boot', () => mock.boot)
11
- jest.mock('../src/state', () => mock.state)
13
+ mocking.module('@toa.io/boot', { namedExports: mock.boot })
14
+ mocking.module('../src/state', { namedExports: mock.state })
12
15
 
13
- const { state } = require('../src/state')
14
- const stage = require('../')
16
+ const { state } = await import('../src/state.js')
17
+ const stage = await import('../src/index.js')
15
18
 
16
19
  beforeEach(() => {
17
- jest.clearAllMocks()
20
+ resetCalls()
18
21
  })
19
22
 
20
23
  it('should be', () => {
21
- expect(stage.shutdown).toBeDefined()
24
+ assert.notStrictEqual(stage.shutdown, undefined)
22
25
  })
23
26
 
24
27
  it('should disconnect components', async () => {
@@ -27,7 +30,7 @@ it('should disconnect components', async () => {
27
30
 
28
31
  await stage.shutdown()
29
32
 
30
- expect(component.disconnect).toHaveBeenCalled()
33
+ assert.ok(component.disconnect.mock.callCount() > 0)
31
34
  })
32
35
 
33
36
  it('should disconnect compositions', async () => {
@@ -36,9 +39,9 @@ it('should disconnect compositions', async () => {
36
39
  await stage.composition(paths)
37
40
  await stage.shutdown()
38
41
 
39
- const composition = await mock.boot.composition.mock.results[0].value
42
+ const composition = await mock.boot.composition.mock.calls[0].result
40
43
 
41
- expect(composition.disconnect).toHaveBeenCalled()
44
+ assert.ok(composition.disconnect.mock.callCount() > 0)
42
45
  })
43
46
 
44
47
  it('should disconnect remotes', async () => {
@@ -47,11 +50,21 @@ it('should disconnect remotes', async () => {
47
50
  const remote = await stage.remote(id)
48
51
  await stage.shutdown()
49
52
 
50
- expect(remote.disconnect).toHaveBeenCalled()
53
+ assert.ok(remote.disconnect.mock.callCount() > 0)
51
54
  })
52
55
 
53
56
  it('should reset state', async () => {
54
57
  await stage.shutdown()
55
58
 
56
- expect(state.reset).toHaveBeenCalled()
59
+ assert.ok(state.reset.mock.callCount() > 0)
57
60
  })
61
+
62
+ function resetCalls (target = [assert, mock, stage], seen = new Set()) {
63
+ if (target === null || typeof target !== 'object' || seen.has(target)) return
64
+
65
+ seen.add(target)
66
+
67
+ for (const value of Object.values(target))
68
+ if (typeof value === 'function' && value.mock !== undefined) value.mock.resetCalls()
69
+ else resetCalls(value, seen)
70
+ }
@@ -1,8 +1,7 @@
1
- 'use strict'
1
+ import { mock } from 'node:test'
2
2
 
3
- const original = jest.requireActual('../src/state')
3
+ // this module defines the replacement, so it still sees the real one
4
+ import * as original from '../src/state.js'
4
5
 
5
- const reset = jest.fn(() => original.state.reset())
6
- const state = { ...original.state, reset }
7
-
8
- module.exports = { state }
6
+ const reset = mock.fn(() => original.state.reset())
7
+ export const state = { ...original.state, reset }
@@ -1,9 +1,10 @@
1
- 'use strict'
1
+ import { it } from 'node:test'
2
+ import assert from 'node:assert/strict'
2
3
 
3
- const { state } = require('../src/state')
4
+ import { state } from '../src/state.js'
4
5
 
5
6
  it('should be', () => {
6
- expect(state).toBeDefined()
7
+ assert.notStrictEqual(state, undefined)
7
8
  })
8
9
 
9
10
  it('should reset', () => {
@@ -11,9 +12,9 @@ it('should reset', () => {
11
12
  const composition = /** @type {toa.core.Connector} */ 2
12
13
  const remote = /** @type {toa.core.Component} */ 3
13
14
 
14
- expect(state.components.length).toStrictEqual(0)
15
- expect(state.compositions.length).toStrictEqual(0)
16
- expect(state.remotes.length).toStrictEqual(0)
15
+ assert.deepStrictEqual(state.components.length, 0)
16
+ assert.deepStrictEqual(state.compositions.length, 0)
17
+ assert.deepStrictEqual(state.remotes.length, 0)
17
18
 
18
19
  state.components.push(component)
19
20
  state.compositions.push(composition)
@@ -21,7 +22,7 @@ it('should reset', () => {
21
22
 
22
23
  state.reset()
23
24
 
24
- expect(state.components.length).toStrictEqual(0)
25
- expect(state.compositions.length).toStrictEqual(0)
26
- expect(state.remotes.length).toStrictEqual(0)
25
+ assert.deepStrictEqual(state.components.length, 0)
26
+ assert.deepStrictEqual(state.compositions.length, 0)
27
+ assert.deepStrictEqual(state.remotes.length, 0)
27
28
  })