@toa.io/extensions.exposition 1.0.0-alpha.272 → 1.0.0-alpha.274

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 (156) hide show
  1. package/CHANGELOG.md +211 -0
  2. package/components/exposition.atom/manifest.toa.yaml +3 -1
  3. package/components/exposition.octets/manifest.toa.yaml +28 -10
  4. package/components/exposition.octets/operations/put.js +20 -5
  5. package/components/identity.bans/manifest.toa.yaml +26 -7
  6. package/components/identity.bans/operations/tsconfig.tsbuildinfo +1 -1
  7. package/components/identity.basic/manifest.toa.yaml +106 -30
  8. package/components/identity.basic/operations/authenticate.js +7 -4
  9. package/components/identity.basic/operations/authenticate.js.map +1 -1
  10. package/components/identity.basic/operations/incept.js +3 -2
  11. package/components/identity.basic/operations/incept.js.map +1 -1
  12. package/components/identity.basic/operations/transit.js +17 -6
  13. package/components/identity.basic/operations/transit.js.map +1 -1
  14. package/components/identity.basic/operations/tsconfig.tsbuildinfo +1 -1
  15. package/components/identity.basic/operations/types.d.ts +2 -2
  16. package/components/identity.basic/source/authenticate.ts +8 -4
  17. package/components/identity.basic/source/incept.ts +3 -2
  18. package/components/identity.basic/source/transit.ts +20 -6
  19. package/components/identity.basic/source/types.ts +2 -2
  20. package/components/identity.credentials/manifest.toa.yaml +34 -13
  21. package/components/identity.credentials/operations/tsconfig.tsbuildinfo +1 -1
  22. package/components/identity.federation/manifest.toa.yaml +120 -28
  23. package/components/identity.federation/operations/authenticate.js +3 -2
  24. package/components/identity.federation/operations/authenticate.js.map +1 -1
  25. package/components/identity.federation/operations/create.js +4 -2
  26. package/components/identity.federation/operations/create.js.map +1 -1
  27. package/components/identity.federation/operations/lib/errors.d.ts +70 -11
  28. package/components/identity.federation/operations/lib/errors.js +40 -11
  29. package/components/identity.federation/operations/lib/errors.js.map +1 -1
  30. package/components/identity.federation/operations/lib/exchange.js +2 -2
  31. package/components/identity.federation/operations/lib/exchange.js.map +1 -1
  32. package/components/identity.federation/operations/tsconfig.tsbuildinfo +1 -1
  33. package/components/identity.federation/operations/types/configuration.d.ts +3 -2
  34. package/components/identity.federation/source/authenticate.ts +3 -2
  35. package/components/identity.federation/source/create.ts +4 -2
  36. package/components/identity.federation/source/lib/errors.ts +49 -12
  37. package/components/identity.federation/source/lib/exchange.ts +2 -2
  38. package/components/identity.federation/source/types/configuration.ts +4 -2
  39. package/components/identity.keys/manifest.toa.yaml +14 -6
  40. package/components/identity.keys/operations/tsconfig.tsbuildinfo +1 -1
  41. package/components/identity.otp/manifest.toa.yaml +44 -15
  42. package/components/identity.otp/operations/authenticate.js +9 -4
  43. package/components/identity.otp/operations/authenticate.js.map +1 -1
  44. package/components/identity.otp/operations/tsconfig.tsbuildinfo +1 -1
  45. package/components/identity.otp/source/authenticate.ts +11 -4
  46. package/components/identity.passkeys/manifest.toa.yaml +38 -8
  47. package/components/identity.passkeys/operations/authenticate.js +3 -2
  48. package/components/identity.passkeys/operations/authenticate.js.map +1 -1
  49. package/components/identity.passkeys/operations/create.js +6 -3
  50. package/components/identity.passkeys/operations/create.js.map +1 -1
  51. package/components/identity.passkeys/operations/tsconfig.tsbuildinfo +1 -1
  52. package/components/identity.passkeys/operations/use.js +6 -3
  53. package/components/identity.passkeys/operations/use.js.map +1 -1
  54. package/components/identity.passkeys/source/authenticate.ts +3 -2
  55. package/components/identity.passkeys/source/create.ts +7 -3
  56. package/components/identity.passkeys/source/use.ts +7 -3
  57. package/components/identity.roles/manifest.toa.yaml +41 -10
  58. package/components/identity.roles/operations/grant.js +3 -2
  59. package/components/identity.roles/operations/grant.js.map +1 -1
  60. package/components/identity.roles/operations/tsconfig.tsbuildinfo +1 -1
  61. package/components/identity.roles/source/grant.ts +3 -2
  62. package/components/identity.tokens/manifest.toa.yaml +99 -39
  63. package/components/identity.tokens/operations/authenticate.js +6 -3
  64. package/components/identity.tokens/operations/authenticate.js.map +1 -1
  65. package/components/identity.tokens/operations/decrypt.js +10 -5
  66. package/components/identity.tokens/operations/decrypt.js.map +1 -1
  67. package/components/identity.tokens/operations/encrypt.js +4 -3
  68. package/components/identity.tokens/operations/encrypt.js.map +1 -1
  69. package/components/identity.tokens/operations/lib/types.d.ts +3 -2
  70. package/components/identity.tokens/operations/tsconfig.tsbuildinfo +1 -1
  71. package/components/identity.tokens/source/authenticate.test.ts +7 -2
  72. package/components/identity.tokens/source/authenticate.ts +7 -3
  73. package/components/identity.tokens/source/decrypt.test.ts +13 -7
  74. package/components/identity.tokens/source/decrypt.ts +12 -5
  75. package/components/identity.tokens/source/encrypt.test.ts +9 -4
  76. package/components/identity.tokens/source/encrypt.ts +4 -3
  77. package/components/identity.tokens/source/lib/types.ts +3 -2
  78. package/context.toa.yaml +2 -2
  79. package/documentation/components.md +1 -1
  80. package/documentation/identity.md +4 -1
  81. package/features/configuration.feature +207 -0
  82. package/features/cors.feature +1 -1
  83. package/features/dev.feature +1 -1
  84. package/features/identity.federation.feature +18 -9
  85. package/features/{identtiy.tokens.custom.feature → identity.tokens.custom.feature} +39 -0
  86. package/features/introspection.map.feature +16 -0
  87. package/features/map.feature +1 -1
  88. package/features/octets.download.feature +1 -1
  89. package/features/octets.meta.feature +1 -1
  90. package/features/passkeys.feature +8 -8
  91. package/features/require.feature +2 -2
  92. package/features/response.feature +3 -3
  93. package/features/steps/Components.ts +41 -4
  94. package/features/steps/Gateway.ts +61 -23
  95. package/features/steps/HTTP.ts +3 -5
  96. package/features/steps/Parameters.ts +2 -3
  97. package/features/steps/Realtime.ts +4 -4
  98. package/features/steps/Workspace.ts +8 -3
  99. package/features/steps/components/audit/manifest.toa.yaml +12 -5
  100. package/features/steps/components/echo/manifest.toa.yaml +33 -8
  101. package/features/steps/components/notify/manifest.toa.yaml +12 -5
  102. package/features/steps/components/octets.tester/manifest.toa.yaml +43 -14
  103. package/features/steps/components/orders/manifest.toa.yaml +22 -5
  104. package/features/steps/components/pots/manifest.toa.yaml +71 -17
  105. package/features/steps/components/pricing/manifest.toa.yaml +8 -2
  106. package/features/steps/components/sequences/manifest.toa.yaml +3 -1
  107. package/features/steps/components/users/manifest.toa.yaml +18 -3
  108. package/features/steps/components/users.properties/manifest.toa.yaml +12 -2
  109. package/package.json +5 -6
  110. package/schemas/annotation.cos.yaml +37 -17
  111. package/schemas/directive.cos.yaml +7 -3
  112. package/schemas/io/throttle.cos.yaml +47 -8
  113. package/schemas/method.cos.yaml +21 -9
  114. package/schemas/node.cos.yaml +22 -7
  115. package/schemas/octets/delete.cos.yaml +15 -2
  116. package/schemas/octets/get.cos.yaml +5 -2
  117. package/schemas/octets/put.cos.yaml +6 -3
  118. package/schemas/octets/workflow.cos.yaml +0 -1
  119. package/schemas/query.cos.yaml +31 -14
  120. package/schemas/querystring.cos.yaml +19 -9
  121. package/schemas/range.cos.yaml +10 -2
  122. package/schemas/route.cos.yaml +6 -2
  123. package/source/Branch.test.ts +37 -0
  124. package/source/Branch.ts +37 -0
  125. package/source/Factory.ts +5 -5
  126. package/source/Gateway.ts +20 -13
  127. package/source/HTTP/formats/yaml.test.ts +10 -2
  128. package/source/HTTP/formats/yaml.ts +21 -1
  129. package/source/RTD/Tree.ts +4 -1
  130. package/source/Tenant.ts +3 -3
  131. package/source/deployment.ts +3 -4
  132. package/source/directives/map/Headers.ts +8 -1
  133. package/source/directives/octets/Put.ts +6 -3
  134. package/source/root.ts +2 -2
  135. package/transpiled/Branch.d.ts +23 -0
  136. package/transpiled/Branch.js +16 -0
  137. package/transpiled/Branch.js.map +1 -1
  138. package/transpiled/Factory.js +4 -4
  139. package/transpiled/Factory.js.map +1 -1
  140. package/transpiled/Gateway.js +17 -7
  141. package/transpiled/Gateway.js.map +1 -1
  142. package/transpiled/HTTP/formats/yaml.js +15 -1
  143. package/transpiled/HTTP/formats/yaml.js.map +1 -1
  144. package/transpiled/RTD/Tree.js +4 -1
  145. package/transpiled/RTD/Tree.js.map +1 -1
  146. package/transpiled/Tenant.d.ts +1 -1
  147. package/transpiled/Tenant.js +1 -1
  148. package/transpiled/Tenant.js.map +1 -1
  149. package/transpiled/deployment.js +3 -4
  150. package/transpiled/deployment.js.map +1 -1
  151. package/transpiled/directives/map/Headers.js +7 -1
  152. package/transpiled/directives/map/Headers.js.map +1 -1
  153. package/transpiled/directives/octets/Put.js.map +1 -1
  154. package/transpiled/root.js +1 -1
  155. package/transpiled/root.js.map +1 -1
  156. package/transpiled/tsconfig.tsbuildinfo +1 -1
@@ -2,9 +2,22 @@ name: pots
2
2
 
3
3
  entity:
4
4
  schema:
5
- title: string(64)
6
- volume: number(0, 1000]
7
- temperature?: number(0, 300]
5
+ properties:
6
+ title:
7
+ type: string
8
+ maxLength: 64
9
+ volume:
10
+ type: number
11
+ exclusiveMinimum: 0
12
+ maximum: 1000
13
+ temperature:
14
+ type: number
15
+ exclusiveMinimum: 0
16
+ maximum: 300
17
+ type: object
18
+ required:
19
+ - title
20
+ - volume
8
21
  index:
9
22
  text:
10
23
  title: text
@@ -14,27 +27,68 @@ operations:
14
27
  query: false
15
28
  forward: transit
16
29
  input:
17
- title*: .
18
- volume*: .
19
- temperature: .
30
+ properties:
31
+ temperature:
32
+ type: string
33
+ default: .
34
+ title:
35
+ type: string
36
+ default: .
37
+ volume:
38
+ type: string
39
+ default: .
40
+ type: object
41
+ required:
42
+ - title
43
+ - volume
20
44
  errors:
21
45
  - NO_WAY
22
46
  - WONT_CREATE
23
47
  transit:
24
48
  concurrency: retry
25
49
  input:
26
- title: .
27
- volume: .
28
- temperature: .
50
+ properties:
51
+ title:
52
+ type: string
53
+ default: .
54
+ volume:
55
+ type: string
56
+ default: .
57
+ temperature:
58
+ type: string
59
+ default: .
60
+ type: object
29
61
  observe:
30
62
  output:
31
- id: string
32
- title: string
33
- volume: number
34
- temperature: number
63
+ properties:
64
+ id:
65
+ type: string
66
+ title:
67
+ type: string
68
+ volume:
69
+ type: number
70
+ temperature:
71
+ type: number
72
+ type: object
35
73
  enumerate:
36
74
  output:
37
- - id: .
38
- title: .
39
- volume: .
40
- temperature?: .
75
+ type: array
76
+ items:
77
+ properties:
78
+ id:
79
+ type: string
80
+ default: .
81
+ title:
82
+ type: string
83
+ default: .
84
+ volume:
85
+ type: string
86
+ default: .
87
+ temperature:
88
+ type: string
89
+ default: .
90
+ type: object
91
+ required:
92
+ - id
93
+ - title
94
+ - volume
@@ -3,5 +3,11 @@ name: pricing
3
3
  operations:
4
4
  quote:
5
5
  input:
6
- volume*: number
7
- output: number
6
+ properties:
7
+ volume:
8
+ type: number
9
+ type: object
10
+ required:
11
+ - volume
12
+ output:
13
+ type: number
@@ -2,7 +2,9 @@ name: sequences
2
2
 
3
3
  operations:
4
4
  numbers:
5
- input: 5
5
+ input:
6
+ type: number
7
+ default: 5
6
8
 
7
9
  exposition:
8
10
  /tokens:
@@ -2,15 +2,30 @@ name: users
2
2
 
3
3
  entity:
4
4
  schema:
5
- name: string
5
+ properties:
6
+ name:
7
+ type: string
8
+ type: object
6
9
 
7
10
  operations:
8
11
  transit:
9
12
  concurrency: retry
10
13
  input:
11
- name*: .
14
+ properties:
15
+ name:
16
+ type: string
17
+ default: .
18
+ type: object
19
+ required:
20
+ - name
12
21
  create:
13
22
  concurrency: retry
14
23
  query: false
15
24
  input:
16
- name*: .
25
+ properties:
26
+ name:
27
+ type: string
28
+ default: .
29
+ type: object
30
+ required:
31
+ - name
@@ -3,11 +3,21 @@ name: properties
3
3
 
4
4
  entity:
5
5
  schema:
6
- newbie: false
6
+ properties:
7
+ newbie:
8
+ type: boolean
9
+ default: false
10
+ type: object
7
11
  associated: true
8
12
 
9
13
  operations:
10
14
  transit:
11
15
  concurrency: retry
12
16
  input:
13
- newbie*: .
17
+ properties:
18
+ newbie:
19
+ type: string
20
+ default: .
21
+ type: object
22
+ required:
23
+ - newbie
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toa.io/extensions.exposition",
3
- "version": "1.0.0-alpha.272",
3
+ "version": "1.0.0-alpha.274",
4
4
  "description": "Toa Exposition",
5
5
  "author": "temich <tema.gurtovoy@gmail.com>",
6
6
  "homepage": "https://github.com/toa-io/toa#readme",
@@ -18,12 +18,11 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@simplewebauthn/server": "13.3.3",
21
- "@toa.io/core": "1.0.0-alpha.272",
22
- "@toa.io/generic": "1.0.0-alpha.272",
23
- "@toa.io/schemas": "1.0.0-alpha.272",
21
+ "@toa.io/core": "1.0.0-alpha.273",
22
+ "@toa.io/generic": "1.0.0-alpha.273",
23
+ "@toa.io/schemas": "1.0.0-alpha.274",
24
24
  "bcryptjs": "3.0.3",
25
25
  "content-type": "2.1.0",
26
- "error-value": "0.4.4",
27
26
  "jose": "6.2.10",
28
27
  "js-yaml": "5.4.1",
29
28
  "lru-cache": "11.5.2",
@@ -62,5 +61,5 @@
62
61
  },
63
62
  "testEnvironment": "node"
64
63
  },
65
- "gitHead": "1a451755445935c04cf5b373bcc73942cac0bb10"
64
+ "gitHead": "7df32eb2872155c45681c299036b1efbeefd6518"
66
65
  }
@@ -1,17 +1,37 @@
1
- authorities*: <string>
2
- class: string
3
- resources:
4
- # `null` deploys the service without any, which every deployment has to state one way
5
- # or the other — see `migrations/263.md`.
6
- type: object
7
- nullable: true
8
- properties:
9
- cpu: &constraint
10
- type: array
11
- items: { type: string }
12
- minItems: 2
13
- maxItems: 2
14
- memory: *constraint
15
- annotations: <string>
16
- debug: boolean
17
- /: ~
1
+ properties:
2
+ class:
3
+ type: string
4
+ resources:
5
+ # `null` deploys the service without any, which every deployment has to state one way
6
+ # or the other — see `migrations/263.md`.
7
+ type: object
8
+ nullable: true
9
+ properties:
10
+ cpu:
11
+ type: array
12
+ items:
13
+ type: string
14
+ minItems: 2
15
+ maxItems: 2
16
+ memory:
17
+ type: array
18
+ items:
19
+ type: string
20
+ minItems: 2
21
+ maxItems: 2
22
+ annotations:
23
+ type: object
24
+ patternProperties:
25
+ ^.+$:
26
+ type: string
27
+ debug:
28
+ type: boolean
29
+ /: {}
30
+ authorities:
31
+ type: object
32
+ patternProperties:
33
+ ^.+$:
34
+ type: string
35
+ type: object
36
+ required:
37
+ - authorities
@@ -1,3 +1,7 @@
1
- family: string
2
- name: string
3
- value: ~
1
+ properties:
2
+ family:
3
+ type: string
4
+ name:
5
+ type: string
6
+ value: {}
7
+ type: object
@@ -1,15 +1,20 @@
1
1
  definitions:
2
- component: &component
2
+ component:
3
3
  anyOf:
4
4
  - type: string
5
- enum: [ip, path, route, identity]
5
+ enum:
6
+ - ip
7
+ - path
8
+ - route
9
+ - identity
6
10
  - type: object
7
11
  properties:
8
12
  segment:
9
13
  type: string
10
- required: [segment]
14
+ required:
15
+ - segment
11
16
  additionalProperties: false
12
- condition: &condition
17
+ condition:
13
18
  type: object
14
19
  properties:
15
20
  status:
@@ -18,15 +23,49 @@ type: object
18
23
  properties:
19
24
  key:
20
25
  anyOf:
21
- - *component
26
+ - anyOf:
27
+ - type: string
28
+ enum:
29
+ - ip
30
+ - path
31
+ - route
32
+ - identity
33
+ - type: object
34
+ properties:
35
+ segment:
36
+ type: string
37
+ required:
38
+ - segment
39
+ additionalProperties: false
22
40
  - type: array
23
- items: *component
41
+ items:
42
+ anyOf:
43
+ - type: string
44
+ enum:
45
+ - ip
46
+ - path
47
+ - route
48
+ - identity
49
+ - type: object
50
+ properties:
51
+ segment:
52
+ type: string
53
+ required:
54
+ - segment
55
+ additionalProperties: false
24
56
  minItems: 1
25
57
  condition:
26
58
  anyOf:
27
- - *condition
59
+ - type: object
60
+ properties:
61
+ status:
62
+ type: number
28
63
  - type: array
29
- items: *condition
64
+ items:
65
+ type: object
66
+ properties:
67
+ status:
68
+ type: number
30
69
  minItems: 1
31
70
  requests:
32
71
  type: integer
@@ -1,9 +1,21 @@
1
- verb: /^(GET|HEAD|POST|PUT|PATCH|DELETE|LOCK|UNLOCK)$/
2
- mapping:
3
- namespace: string
4
- component: string
5
- endpoint: string
6
- query:
7
- $ref: query
8
- ...: false
9
- directives: [ref:directive]
1
+ properties:
2
+ verb:
3
+ type: string
4
+ pattern: ^(GET|HEAD|POST|PUT|PATCH|DELETE|LOCK|UNLOCK)$
5
+ mapping:
6
+ properties:
7
+ namespace:
8
+ type: string
9
+ component:
10
+ type: string
11
+ endpoint:
12
+ type: string
13
+ query:
14
+ $ref: query
15
+ additionalProperties: false
16
+ type: object
17
+ directives:
18
+ type: array
19
+ items:
20
+ $ref: directive
21
+ type: object
@@ -1,7 +1,22 @@
1
- protected: boolean
2
- isolated: boolean
3
- forward: string
4
- routes: [ref:route]
5
- methods: [ref:method]
6
- directives: [ref:directive]
7
- version: string
1
+ properties:
2
+ protected:
3
+ type: boolean
4
+ isolated:
5
+ type: boolean
6
+ forward:
7
+ type: string
8
+ routes:
9
+ type: array
10
+ items:
11
+ $ref: route
12
+ methods:
13
+ type: array
14
+ items:
15
+ $ref: method
16
+ directives:
17
+ type: array
18
+ items:
19
+ $ref: directive
20
+ version:
21
+ type: string
22
+ type: object
@@ -1,2 +1,15 @@
1
- workflow+: <string>
2
- _: true
1
+ properties:
2
+ workflow:
3
+ oneOf:
4
+ - type: object
5
+ patternProperties:
6
+ ^.+$:
7
+ type: string
8
+ - type: array
9
+ items:
10
+ type: object
11
+ patternProperties:
12
+ ^.+$:
13
+ type: string
14
+ nullable: true
15
+ type: object
@@ -1,2 +1,5 @@
1
- meta: boolean
2
- _: true
1
+ properties:
2
+ meta:
3
+ type: boolean
4
+ nullable: true
5
+ type: object
@@ -18,11 +18,14 @@ properties:
18
18
  type: string
19
19
  workflow:
20
20
  anyOf:
21
- - &unit
22
- type: object
21
+ - type: object
23
22
  patternProperties:
24
23
  ^.+$:
25
24
  type: string
26
25
  - type: array
27
- items: *unit
26
+ items:
27
+ type: object
28
+ patternProperties:
29
+ ^.+$:
30
+ type: string
28
31
  additionalProperties: false
@@ -4,7 +4,6 @@ definitions:
4
4
  patternProperties:
5
5
  ^[a-zA-Z0-9_]+$:
6
6
  type: string
7
-
8
7
  oneOf:
9
8
  - $ref: '#/definitions/unit'
10
9
  - type: array
@@ -1,14 +1,31 @@
1
- id?: string
2
- criteria?: string
3
- sort?: string
4
- search?: boolean
5
- sample?: integer
6
- omit?:
7
- $ref: range
8
- limit?:
9
- $ref: range
10
- selectors?: [string]
11
- projection?: [string]
12
- parameters?: [string]
13
- deleted?: boolean
14
- _: true
1
+ properties:
2
+ id:
3
+ type: string
4
+ criteria:
5
+ type: string
6
+ sort:
7
+ type: string
8
+ search:
9
+ type: boolean
10
+ sample:
11
+ type: integer
12
+ omit:
13
+ $ref: range
14
+ limit:
15
+ $ref: range
16
+ selectors:
17
+ type: array
18
+ items:
19
+ type: string
20
+ projection:
21
+ type: array
22
+ items:
23
+ type: string
24
+ parameters:
25
+ type: array
26
+ items:
27
+ type: string
28
+ deleted:
29
+ type: boolean
30
+ nullable: true
31
+ type: object
@@ -1,9 +1,19 @@
1
- id: string
2
- criteria: string
3
- search: string
4
- sample: number
5
- sort: string
6
- omit: number
7
- limit: number
8
- version: number
9
- ...: false
1
+ properties:
2
+ id:
3
+ type: string
4
+ criteria:
5
+ type: string
6
+ search:
7
+ type: string
8
+ sample:
9
+ type: number
10
+ sort:
11
+ type: string
12
+ omit:
13
+ type: number
14
+ limit:
15
+ type: number
16
+ version:
17
+ type: number
18
+ additionalProperties: false
19
+ type: object
@@ -1,2 +1,10 @@
1
- value?: number
2
- range: [number]
1
+ properties:
2
+ range:
3
+ type: array
4
+ items:
5
+ type: number
6
+ value:
7
+ type: number
8
+ type: object
9
+ required:
10
+ - range
@@ -1,2 +1,6 @@
1
- path: string
2
- node: ref:node
1
+ properties:
2
+ path:
3
+ type: string
4
+ node:
5
+ $ref: node
6
+ type: object
@@ -0,0 +1,37 @@
1
+ import { decide } from './Branch'
2
+ import type { Branch, Exposed } from './Branch'
3
+
4
+ function branch (version: string, timestamp: number): Branch {
5
+ return {
6
+ namespace: 'default',
7
+ component: 'one',
8
+ isolated: false,
9
+ node: { routes: [], methods: [], directives: [] },
10
+ version,
11
+ timestamp
12
+ }
13
+ }
14
+
15
+ function exposed (version: string, timestamp: number): Exposed {
16
+ return { version, timestamp, nodes: [] }
17
+ }
18
+
19
+ it('should refresh the same version', () => {
20
+ expect(decide(exposed('a', 1), branch('a', 2))).toStrictEqual('refresh')
21
+ })
22
+
23
+ it('should refresh the same version announced by an older tenant', () => {
24
+ expect(decide(exposed('a', 2), branch('a', 1))).toStrictEqual('refresh')
25
+ })
26
+
27
+ it('should merge a newer tenant', () => {
28
+ expect(decide(exposed('a', 1), branch('b', 2))).toStrictEqual('merge')
29
+ })
30
+
31
+ it('should not merge a tenant that started earlier', () => {
32
+ expect(decide(exposed('b', 2), branch('a', 1))).toStrictEqual('superseded')
33
+ })
34
+
35
+ it('should merge when tenants started at the same time', () => {
36
+ expect(decide(exposed('a', 1), branch('b', 1))).toStrictEqual('merge')
37
+ })
package/source/Branch.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type * as RTD from './RTD/syntax'
2
+ import type { Node } from './RTD'
2
3
 
3
4
  export interface Branch {
4
5
  namespace: string
@@ -6,4 +7,40 @@ export interface Branch {
6
7
  isolated: boolean
7
8
  node: RTD.Node
8
9
  version: string
10
+
11
+ /**
12
+ * When the tenant that announced it started, by its own clock. A replica on its way
13
+ * out announces the same component with an older stamp than the one replacing it, and
14
+ * that is what tells the two apart when their versions differ.
15
+ */
16
+ timestamp: number
17
+ }
18
+
19
+ /** A branch the gateway has merged, and the tenant it came from. */
20
+ export interface Exposed {
21
+ version: string
22
+
23
+ /** The start time of the tenant this branch came from. */
24
+ timestamp: number
25
+
26
+ nodes: Node[]
9
27
  }
28
+
29
+ /**
30
+ * What to do with an announcement about a component that already has a branch exposed.
31
+ *
32
+ * - `refresh`: the same version, so its expiration is extended and its endpoints left alone
33
+ * - `superseded`: it came from a tenant that started before the one exposed now
34
+ * - `merge`: everything else
35
+ */
36
+ export function decide (exposed: Exposed, branch: Branch): Decision {
37
+ if (exposed.version === branch.version)
38
+ return 'refresh'
39
+
40
+ if (branch.timestamp < exposed.timestamp)
41
+ return 'superseded'
42
+
43
+ return 'merge'
44
+ }
45
+
46
+ export type Decision = 'merge' | 'refresh' | 'superseded'