@toa.io/extensions.introspection 1.0.0-alpha.291 → 1.0.0-alpha.293

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 (107) hide show
  1. package/package.json +16 -6
  2. package/transpiled/Composition.d.ts +2 -7
  3. package/transpiled/Composition.js +4 -15
  4. package/transpiled/Composition.js.map +1 -1
  5. package/transpiled/Factory.d.ts +1 -1
  6. package/transpiled/Factory.js +2 -2
  7. package/transpiled/Factory.js.map +1 -1
  8. package/transpiled/Reporter.d.ts +1 -1
  9. package/transpiled/Reporter.js +1 -1
  10. package/transpiled/Reporter.js.map +1 -1
  11. package/transpiled/Tenant.js +1 -1
  12. package/transpiled/Tenant.js.map +1 -1
  13. package/transpiled/UI.js +1 -1
  14. package/transpiled/UI.js.map +1 -1
  15. package/transpiled/index.d.ts +1 -3
  16. package/transpiled/index.js +0 -2
  17. package/transpiled/index.js.map +1 -1
  18. package/transpiled/sample.js +1 -1
  19. package/transpiled/sample.js.map +1 -1
  20. package/ui/dist/_app/immutable/chunks/B2kPZfJh.js +1 -0
  21. package/ui/dist/_app/immutable/chunks/{BM_8gmPc.js → B6dxxHIS.js} +1 -1
  22. package/ui/dist/_app/immutable/chunks/BQGufqas.js +6 -0
  23. package/ui/dist/_app/immutable/chunks/{BPmTOjUD.js → CMT3qkok.js} +1 -1
  24. package/ui/dist/_app/immutable/chunks/{ClEi7LqQ.js → CRq6qlvN.js} +1 -1
  25. package/ui/dist/_app/immutable/chunks/{BNP4DAhr.js → Cdb6j7Bw.js} +1 -1
  26. package/ui/dist/_app/immutable/chunks/DFP66uri.js +1 -0
  27. package/ui/dist/_app/immutable/chunks/{D58WJWRP.js → Qo6KLWZ1.js} +1 -1
  28. package/ui/dist/_app/immutable/chunks/jxky52kD.js +1 -0
  29. package/ui/dist/_app/immutable/entry/{app.C__edJT8.js → app.MKQlb7LU.js} +2 -2
  30. package/ui/dist/_app/immutable/entry/start.RcPu9STL.js +1 -0
  31. package/ui/dist/_app/immutable/nodes/{0.DqHzPxwp.js → 0.Gc5w_8Fb.js} +1 -1
  32. package/ui/dist/_app/immutable/nodes/{1.CxKiCrAx.js → 1.CZzwHnag.js} +1 -1
  33. package/ui/dist/_app/immutable/nodes/{2.DiR-utWy.js → 2.DRxH9AhI.js} +1 -1
  34. package/ui/dist/_app/immutable/nodes/3.DXaS4-Wc.js +1 -0
  35. package/ui/dist/_app/immutable/nodes/4.C424lXpX.js +1 -0
  36. package/ui/dist/_app/immutable/nodes/{5.BjL9k_iK.js → 5.BlPcxfID.js} +1 -1
  37. package/ui/dist/_app/version.json +1 -1
  38. package/ui/dist/index.html +12 -12
  39. package/CHANGELOG.md +0 -35
  40. package/components/introspection.edges/tsconfig.tsbuildinfo +0 -1
  41. package/components/introspection.nodes/tsconfig.tsbuildinfo +0 -1
  42. package/cucumber.mjs +0 -8
  43. package/features/calls.feature +0 -123
  44. package/features/nodes.feature +0 -70
  45. package/features/samples.feature +0 -75
  46. package/features/shutdown.feature +0 -37
  47. package/features/site/_app/immutable/asset.js +0 -1
  48. package/features/site/favicon.ico +0 -0
  49. package/features/site/index.html +0 -10
  50. package/features/steps/Map.ts +0 -184
  51. package/features/steps/UI.ts +0 -98
  52. package/features/steps/components/probe.discreet/manifest.toa.yaml +0 -16
  53. package/features/steps/components/probe.discreet/operations/ping.js +0 -3
  54. package/features/steps/components/probe.quiet/manifest.toa.yaml +0 -15
  55. package/features/steps/components/probe.quiet/operations/ping.js +0 -3
  56. package/features/steps/components/probe.source/manifest.toa.yaml +0 -40
  57. package/features/steps/components/probe.source/operations/crash.js +0 -3
  58. package/features/steps/components/probe.source/operations/fail.js +0 -8
  59. package/features/steps/components/probe.source/operations/relay.js +0 -3
  60. package/features/steps/components/probe.target/manifest.toa.yaml +0 -30
  61. package/features/steps/components/probe.target/operations/compute.js +0 -3
  62. package/features/steps/components/probe.target/operations/count.js +0 -5
  63. package/features/steps/config.ts +0 -27
  64. package/features/steps/tsconfig.json +0 -9
  65. package/features/ui.feature +0 -93
  66. package/schemas/annotation.cos.yaml +0 -31
  67. package/schemas/declaration.cos.yaml +0 -5
  68. package/source/Composition.ts +0 -60
  69. package/source/Explorer.ts +0 -16
  70. package/source/Factory.ts +0 -152
  71. package/source/Reporter.ts +0 -209
  72. package/source/Tenant.ts +0 -46
  73. package/source/UI.ts +0 -213
  74. package/source/annotation.ts +0 -87
  75. package/source/const.ts +0 -46
  76. package/source/describe.ts +0 -75
  77. package/source/extension.ts +0 -49
  78. package/source/index.ts +0 -7
  79. package/source/keys.ts +0 -0
  80. package/source/manifest.ts +0 -18
  81. package/source/model.ts +0 -83
  82. package/source/sample.ts +0 -47
  83. package/source/schemas.ts +0 -12
  84. package/transpiled/annotation.d.ts +0 -40
  85. package/transpiled/annotation.js +0 -39
  86. package/transpiled/annotation.js.map +0 -1
  87. package/transpiled/const.d.ts +0 -30
  88. package/transpiled/const.js +0 -35
  89. package/transpiled/const.js.map +0 -1
  90. package/transpiled/extension.d.ts +0 -14
  91. package/transpiled/extension.js +0 -42
  92. package/transpiled/extension.js.map +0 -1
  93. package/transpiled/manifest.d.ts +0 -9
  94. package/transpiled/manifest.js +0 -16
  95. package/transpiled/manifest.js.map +0 -1
  96. package/transpiled/schemas.d.ts +0 -4
  97. package/transpiled/schemas.js +0 -7
  98. package/transpiled/schemas.js.map +0 -1
  99. package/tsconfig.json +0 -13
  100. package/tsconfig.tsbuildinfo +0 -1
  101. package/ui/dist/_app/immutable/chunks/B29ORAfk.js +0 -1
  102. package/ui/dist/_app/immutable/chunks/B2Uho8Qa.js +0 -1
  103. package/ui/dist/_app/immutable/chunks/DJkgMsju.js +0 -6
  104. package/ui/dist/_app/immutable/chunks/xuD-gQB1.js +0 -1
  105. package/ui/dist/_app/immutable/entry/start.1kW6Dv7l.js +0 -1
  106. package/ui/dist/_app/immutable/nodes/3.C4ocqYxG.js +0 -1
  107. package/ui/dist/_app/immutable/nodes/4.BxBsqIXE.js +0 -1
@@ -1,70 +0,0 @@
1
- Feature: Component descriptions
2
-
3
- The static half of the map: what each component is, taken from its manifest
4
- when the composition starts. This is where the event graph lives — which events
5
- a component publishes, and which event each of its receivers takes — since all
6
- of it is declared, and none of it needs traffic to be true.
7
-
8
- Scenario: Describing operations
9
- Then the map contains a node:
10
- """yaml
11
- namespace: probe
12
- component: target
13
- operations:
14
- - endpoint: compute
15
- type: computation
16
- scope: none
17
- input:
18
- type: object
19
- properties:
20
- a: { type: number }
21
- b: { type: number }
22
- output:
23
- type: number
24
- """
25
-
26
- Scenario: Describing the entity
27
- Then the map contains a node:
28
- """yaml
29
- namespace: probe
30
- component: target
31
- entity:
32
- storage: "@toa.io/storages.null"
33
- schema:
34
- properties:
35
- counted:
36
- type: integer
37
- """
38
-
39
- Scenario: Describing events
40
- Then the map contains a node:
41
- """yaml
42
- namespace: probe
43
- component: source
44
- events:
45
- - label: created
46
- - label: updated
47
- - label: deleted
48
- - label: sync
49
- """
50
-
51
- Scenario: Describing receivers
52
- Then the map contains a node:
53
- """yaml
54
- namespace: probe
55
- component: target
56
- receivers:
57
- - label: probe.source.created
58
- source: probe.source
59
- event: created
60
- operation: count
61
- conditioned: false
62
- adaptive: false
63
- """
64
-
65
- Scenario: An opted out component is not described
66
- Then the map contains no node:
67
- """yaml
68
- namespace: probe
69
- component: quiet
70
- """
@@ -1,75 +0,0 @@
1
- Feature: Payload samples
2
-
3
- Samples are real user data, so they are captured only when the context and the
4
- component both allow it. Either level can veto.
5
-
6
- Scenario: Nothing is captured by default
7
- When the `probe.target.compute` is called with:
8
- """yaml
9
- input:
10
- a: 4
11
- b: 5
12
- """
13
- Then the map contains an edge:
14
- """yaml
15
- dst:
16
- namespace: probe
17
- component: target
18
- operation: compute
19
- """
20
- And the map contains no edge:
21
- """yaml
22
- dst:
23
- namespace: probe
24
- component: target
25
- operation: compute
26
- sample:
27
- input:
28
- a: 4
29
- """
30
-
31
- @samples
32
- Scenario: The context enables capturing
33
- When the `probe.target.compute` is called with:
34
- """yaml
35
- input:
36
- a: 4
37
- b: 5
38
- """
39
- Then the map contains an edge:
40
- """yaml
41
- dst:
42
- namespace: probe
43
- component: target
44
- operation: compute
45
- sample:
46
- outcome: ok
47
- input:
48
- a: 4
49
- b: 5
50
- """
51
-
52
- @samples
53
- Scenario: A component vetoes capturing for itself
54
- When the `probe.discreet.ping` is called with:
55
- """yaml
56
- input:
57
- a: 7
58
- """
59
- Then the map contains an edge:
60
- """yaml
61
- dst:
62
- namespace: probe
63
- component: discreet
64
- operation: ping
65
- """
66
- And the map contains no edge:
67
- """yaml
68
- dst:
69
- namespace: probe
70
- component: discreet
71
- operation: ping
72
- sample:
73
- input:
74
- a: 7
75
- """
@@ -1,37 +0,0 @@
1
- @shutdown
2
- Feature: Graceful shutdown
3
-
4
- A component reports on a timer, so whatever it observed since the last report
5
- would be lost on a deploy. Stopping flushes it instead: the collector drains
6
- its buffer while its remotes are still connected.
7
-
8
- This suite runs with a flush period long enough that the timer cannot fire,
9
- so nothing here reaches the map unless the shutdown does it.
10
-
11
- Scenario: Observations are flushed on shutdown
12
- When the `probe.source.relay` is called with:
13
- """yaml
14
- input:
15
- a: 2
16
- b: 3
17
- """
18
- And the components are stopped
19
- Then the map contains an edge:
20
- """yaml
21
- src:
22
- namespace: probe
23
- component: source
24
- operation: relay
25
- dst:
26
- namespace: probe
27
- component: target
28
- operation: compute
29
- """
30
-
31
- Scenario: Component descriptions are flushed on shutdown
32
- When the components are stopped
33
- Then the map contains a node:
34
- """yaml
35
- namespace: probe
36
- component: target
37
- """
@@ -1 +0,0 @@
1
- export const hashed = true
Binary file
@@ -1,10 +0,0 @@
1
- <!doctype html>
2
- <!-- stands in for what `ui` builds; the scenarios are about the server, not the page -->
3
- <html lang="en">
4
- <head>
5
- <title>fixture</title>
6
- </head>
7
- <body>
8
- the page
9
- </body>
10
- </html>
@@ -1,184 +0,0 @@
1
- import assert from 'node:assert'
2
- import { resolve } from 'node:path'
3
- import { readdirSync } from 'node:fs'
4
- import { setTimeout } from 'node:timers/promises'
5
- import { MongoClient } from 'mongodb'
6
- import tsflow from 'cucumber-tsflow'
7
-
8
- import { load as parse } from 'js-yaml'
9
- import { match } from '@toa.io/generic'
10
- import * as boot from '@toa.io/boot'
11
- import { Locator } from '@toa.io/core'
12
- import * as stage from '@toa.io/userland/stage'
13
- import { Factory } from '../../source/index.js'
14
- import type { Component, Connector } from '@toa.io/core'
15
- import type { Request } from '@toa.io/core/types'
16
-
17
- const { after, before, binding, then, when } = tsflow
18
-
19
- @binding()
20
- export class Map {
21
- private service: Connector | null = null
22
- private composition: Connector | null = null
23
- private remotes: Record<string, Component> = {}
24
- private unidentified: Component | null = null
25
-
26
- @when('the `{word}` is called with:')
27
- public async call(endpoint: string, yaml: string): Promise<void> {
28
- const request = parse(yaml) as Request
29
- const [operation, component, namespace = 'default'] = endpoint.split('.').reverse()
30
-
31
- // an operation may throw, and that is exactly what one of the scenarios is about
32
- await this.invoke(`${namespace}.${component}`, operation, request).catch(
33
- () => undefined
34
- )
35
- }
36
-
37
- /**
38
- * The stage names itself as the caller, as every entry point does; a call that names
39
- * nobody is made past it, straight through a remote of its own.
40
- */
41
- @when('the `{word}` is called by an unidentified caller with:')
42
- public async callUnidentified(endpoint: string, yaml: string): Promise<void> {
43
- const request = parse(yaml) as Request
44
- const [operation, component, namespace = 'default'] = endpoint.split('.').reverse()
45
-
46
- this.unidentified ??= await boot.remote(new Locator(component, namespace))
47
-
48
- await this.unidentified.connect()
49
- await this.unidentified.invoke(operation, request).catch(() => undefined)
50
- }
51
-
52
- @then('the map contains a node:')
53
- public async node(yaml: string): Promise<void> {
54
- await this.eventually('introspection.nodes', parse(yaml) as object)
55
- }
56
-
57
- @then('the map contains an edge:')
58
- public async edge(yaml: string): Promise<void> {
59
- await this.eventually('introspection.edges', parse(yaml) as object)
60
- }
61
-
62
- @then('the map contains no node:')
63
- public async noNode(yaml: string): Promise<void> {
64
- await this.never('introspection.nodes', parse(yaml) as object)
65
- }
66
-
67
- @then('the map contains no edge:')
68
- public async noEdge(yaml: string): Promise<void> {
69
- await this.never('introspection.edges', parse(yaml) as object)
70
- }
71
-
72
- @when('the components are stopped')
73
- public async stop(): Promise<void> {
74
- await this.composition?.disconnect()
75
-
76
- this.composition = null
77
- }
78
-
79
- @before('not @ui')
80
- public async run(): Promise<void> {
81
- await clean()
82
-
83
- this.service = (await new Factory(boot.host()).service())!
84
-
85
- await this.service.connect()
86
-
87
- // booted here rather than through the stage, so that a scenario can stop it on its own
88
- this.composition = await boot.composition(components())
89
-
90
- await this.composition.connect()
91
- }
92
-
93
- @after('not @ui')
94
- public async shutdown(): Promise<void> {
95
- this.remotes = {}
96
-
97
- await this.unidentified?.disconnect()
98
- await this.composition?.disconnect()
99
- await stage.shutdown()
100
- await this.service?.disconnect()
101
-
102
- this.composition = null
103
- this.service = null
104
- this.unidentified = null
105
- }
106
-
107
- private async invoke(
108
- id: string,
109
- operation: string,
110
- request: Request
111
- ): Promise<unknown> {
112
- this.remotes[id] ??= await stage.remote(id)
113
-
114
- return await this.remotes[id].invoke(operation, request)
115
- }
116
-
117
- /** The map is eventually consistent: the collector buffers, flushes, and the task is queued. */
118
- private async eventually(id: string, expected: object): Promise<void> {
119
- const deadline = Date.now() + DEADLINE
120
-
121
- let records: any[] = []
122
-
123
- while (Date.now() < deadline) {
124
- records = await this.list(id)
125
-
126
- if (records.some((record) => match(record, expected))) return
127
-
128
- await setTimeout(POLL)
129
- }
130
-
131
- assert.fail(
132
- `No record in '${id}' matches\n${JSON.stringify(expected, null, 2)}\n\n` +
133
- `Present:\n${JSON.stringify(records, null, 2)}`
134
- )
135
- }
136
-
137
- /** Absence has to outlive a flush, otherwise it only proves the map is slow. */
138
- private async never(id: string, expected: object): Promise<void> {
139
- await setTimeout(SETTLE)
140
-
141
- const records = await this.list(id)
142
- const found = records.find((record) => match(record, expected))
143
-
144
- assert.equal(
145
- found,
146
- undefined,
147
- `Unexpected record in '${id}':\n${JSON.stringify(found, null, 2)}`
148
- )
149
- }
150
-
151
- private async list(id: string): Promise<any[]> {
152
- return (await this.invoke(id, 'enumerate', { query: { limit: 100 } })) as any[]
153
- }
154
- }
155
-
156
- async function clean(): Promise<void> {
157
- const client = new MongoClient(URL)
158
-
159
- await client.connect()
160
-
161
- const db = client.db(DB)
162
-
163
- await Promise.all([
164
- db.collection('introspection_nodes').deleteMany({}),
165
- db.collection('introspection_edges').deleteMany({})
166
- ])
167
-
168
- await client.close()
169
- }
170
-
171
- function components(): string[] {
172
- const entries = readdirSync(ROOT, { withFileTypes: true })
173
-
174
- return entries
175
- .filter((entry) => entry.isDirectory())
176
- .map((entry) => resolve(ROOT, entry.name))
177
- }
178
-
179
- const ROOT = resolve(import.meta.dirname, 'components')
180
- const URL = 'mongodb://developer:secret@localhost:31020'
181
- const DB = 'toa-dev'
182
- const DEADLINE = 20_000
183
- const POLL = 250
184
- const SETTLE = 4_000
@@ -1,98 +0,0 @@
1
- import assert from 'node:assert'
2
- import * as http from 'node:http'
3
- import { resolve } from 'node:path'
4
- import tsflow from 'cucumber-tsflow'
5
-
6
- import { UI } from '../../source/UI.js'
7
-
8
- const { after, binding, given, then, when } = tsflow
9
-
10
- /**
11
- * Not `UI_PORT`, which a deployment serves the page on: an application built on Toa is served
12
- * on this machine too, and its own explorer holds that one. See CONTRIBUTING.md.
13
- */
14
- const PORT = 31002
15
-
16
- /**
17
- * The scenarios are about the server, not about the page: it is pointed at a fixture
18
- * directory, so that running them never needs a UI build.
19
- */
20
- @binding()
21
- export class Site {
22
- private server: UI | null = null
23
- private response: Response | null = null
24
-
25
- @given('the UI is published')
26
- public async publish(): Promise<void> {
27
- this.server = new UI(PORT, resolve(import.meta.dirname, '..', 'site'))
28
-
29
- await this.server.connect()
30
- }
31
-
32
- @when('{string} is requested')
33
- public async request(path: string): Promise<void> {
34
- this.response = await get(path)
35
- }
36
-
37
- @then('the status is {int}')
38
- public statusIs(status: number): void {
39
- assert.equal(this.response?.status, status)
40
- }
41
-
42
- @then('the body contains {string}')
43
- public bodyContains(text: string): void {
44
- assert.ok(
45
- this.response?.body.includes(text),
46
- `Expected the body to contain '${text}', got '${this.response?.body}'`
47
- )
48
- }
49
-
50
- @then('the body is empty')
51
- public bodyIsEmpty(): void {
52
- assert.equal(this.response?.body, '')
53
- }
54
-
55
- @then('the {string} header is {string}')
56
- public headerIs(name: string, value: string): void {
57
- assert.equal(this.response?.headers[name], value)
58
- }
59
-
60
- @after()
61
- public async shutdown(): Promise<void> {
62
- await this.server?.disconnect()
63
-
64
- this.server = null
65
- this.response = null
66
- }
67
- }
68
-
69
- /**
70
- * Raw `http`, not `fetch`: the URL parser normalizes `%2e%2e` away, and one of the
71
- * scenarios is about exactly that segment reaching the server.
72
- */
73
- async function get(path: string): Promise<Response> {
74
- return await new Promise((resolve, reject) => {
75
- // `agent: false` — a keep-alive socket outlives the scenario that opened it
76
- const request = http.get({ port: PORT, path, agent: false }, (response) => {
77
- let body = ''
78
-
79
- response.setEncoding('utf8')
80
- response.on('data', (chunk: string) => (body += chunk))
81
- response.on('end', () => {
82
- resolve({
83
- status: response.statusCode!,
84
- headers: response.headers as Record<string, string>,
85
- body
86
- })
87
- })
88
- })
89
-
90
- request.on('error', reject)
91
- })
92
- }
93
-
94
- interface Response {
95
- status: number
96
- headers: Record<string, string>
97
- body: string
98
- }
@@ -1,16 +0,0 @@
1
- namespace: probe
2
- name: discreet
3
-
4
- # on the map, but its payloads are never captured
5
- introspection:
6
- samples: false
7
-
8
- operations:
9
- ping:
10
- input:
11
- properties:
12
- a:
13
- type: number
14
- type: object
15
- output:
16
- type: number
@@ -1,3 +0,0 @@
1
- export async function computation(input) {
2
- return input.a
3
- }
@@ -1,15 +0,0 @@
1
- namespace: probe
2
- name: quiet
3
-
4
- # opted out entirely: neither described nor instrumented
5
- introspection: false
6
-
7
- operations:
8
- ping:
9
- input:
10
- properties:
11
- a:
12
- type: number
13
- type: object
14
- output:
15
- type: number
@@ -1,3 +0,0 @@
1
- export async function computation(input) {
2
- return input.a
3
- }
@@ -1,40 +0,0 @@
1
- namespace: probe
2
- name: source
3
-
4
- entity:
5
- associated: true
6
- storage: null
7
- properties:
8
- value:
9
- type: integer
10
- secret:
11
- type: string
12
- blank:
13
- value: 0
14
-
15
- operations:
16
- transit:
17
- concurrency: retry
18
- input:
19
- properties:
20
- value:
21
- type: string
22
- default: .
23
- secret:
24
- type: string
25
- default: .
26
- type: object
27
- relay:
28
- input:
29
- properties:
30
- a:
31
- type: number
32
- b:
33
- type: number
34
- type: object
35
- output:
36
- type: number
37
- crash: {}
38
- fail:
39
- errors:
40
- - NOPE
@@ -1,3 +0,0 @@
1
- export function computation(input) {
2
- throw new Error('crashed on purpose')
3
- }
@@ -1,8 +0,0 @@
1
- export function computation(input) {
2
- return NOPE
3
- }
4
-
5
- const NOPE = Object.create(Error.prototype, {
6
- code: { value: 'NOPE' },
7
- message: { value: 'declined on purpose', enumerable: true }
8
- })
@@ -1,3 +0,0 @@
1
- export async function computation(input, context) {
2
- return context.remote.probe.target.compute({ input })
3
- }
@@ -1,30 +0,0 @@
1
- namespace: probe
2
- name: target
3
-
4
- entity:
5
- storage: null
6
- properties:
7
- counted:
8
- type: integer
9
- blank:
10
- counted: 0
11
-
12
- operations:
13
- compute:
14
- input:
15
- properties:
16
- a:
17
- type: number
18
- b:
19
- type: number
20
- type: object
21
- output:
22
- type: number
23
- count:
24
- concurrency: retry
25
- input:
26
- type: object
27
- additionalProperties: true
28
-
29
- receivers:
30
- probe.source.created: count
@@ -1,3 +0,0 @@
1
- export async function computation(input) {
2
- return input.a + input.b
3
- }
@@ -1,5 +0,0 @@
1
- export function transition(input, object) {
2
- object.counted++
3
-
4
- return object
5
- }
@@ -1,27 +0,0 @@
1
- import { setDefaultTimeout } from '@cucumber/cucumber'
2
- import { environment } from '@toa.io/generic'
3
-
4
- environment.set('TOA_DEV', '1')
5
-
6
- // a reply is checked against what the operation declares, so the suite runs Toa under the
7
- // contract it asks applications to keep
8
- if (!environment.has('TOA_ENV')) environment.set('TOA_ENV', 'local')
9
-
10
- /*
11
- * The extension factory reads the environment once, and the bootloader caches
12
- * factories per process — so the context level of the annotation is fixed for
13
- * a whole run. `npm run features` therefore makes a pass per configuration.
14
- */
15
- environment.set(
16
- 'TOA_INTROSPECTION',
17
- JSON.stringify({
18
- samples: environment.get('TOA_INTROSPECTION_SAMPLES') === '1',
19
- interval: Number(environment.get('TOA_INTROSPECTION_INTERVAL') ?? 1),
20
- threshold: 64,
21
-
22
- // `ui.feature` starts its own server; the explorer must not take the port first
23
- ui: false
24
- })
25
- )
26
-
27
- setDefaultTimeout(60 * 1000)
@@ -1,9 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ESNext",
4
- "noEmit": true,
5
- "moduleResolution": "node",
6
- "experimentalDecorators": true,
7
- "emitDecoratorMetadata": true
8
- }
9
- }