@reventlessdev/reventless-core 3.0.0-alpha.177 → 3.0.0-alpha.178
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,13 @@
|
|
|
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
|
+
# 3.0.0-alpha.178 (2026-07-22)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **core:** derive the disconnect schedule's rule name in one place ([6324a5b](https://github.com/ReventlessDev/reventless-core/commit/6324a5bc678a375688ec98571423f164b09375ae))
|
|
11
|
+
|
|
12
|
+
|
|
6
13
|
# 3.0.0-alpha.177 (2026-07-22)
|
|
7
14
|
|
|
8
15
|
* refactor!: retire the stale "Admin" vocabulary for platform-owned resources ([2770bd9](https://github.com/ReventlessDev/reventless-core/commit/2770bd96f309142bdfc65b9f36bd1a3ef60641bd))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-core",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.178",
|
|
4
4
|
"description": "Core package for Reventless framework",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -29,16 +29,16 @@
|
|
|
29
29
|
"sury": "11.0.0-alpha.4",
|
|
30
30
|
"uuid": "^13.0.0",
|
|
31
31
|
"@reventlessdev/rescript-effect": "0.1.0-alpha.30",
|
|
32
|
-
"@reventlessdev/rescript-hash-object": "1.2.0-alpha.13",
|
|
33
32
|
"@reventlessdev/rescript-fast-csv": "1.2.0-alpha.14",
|
|
34
|
-
"@reventlessdev/rescript-
|
|
33
|
+
"@reventlessdev/rescript-hash-object": "1.2.0-alpha.13",
|
|
35
34
|
"@reventlessdev/rescript-jest": "1.0.0-alpha.9",
|
|
36
|
-
"@reventlessdev/rescript-
|
|
35
|
+
"@reventlessdev/rescript-node-streams": "1.1.0-alpha.13",
|
|
37
36
|
"@reventlessdev/rescript-ssh2": "1.1.0-alpha.14",
|
|
37
|
+
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.17",
|
|
38
38
|
"@reventlessdev/rescript-uuid": "1.1.0-alpha.17",
|
|
39
|
-
"@reventlessdev/reventless-spec": "3.0.0-alpha.80",
|
|
40
39
|
"@reventlessdev/reventless-interop": "3.0.0-alpha.29",
|
|
41
|
-
"@reventlessdev/reventless-infra": "3.0.0-alpha.104"
|
|
40
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.104",
|
|
41
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.80"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"rescript": "12.3.0",
|
|
@@ -29,6 +29,13 @@ module type Spec = {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
module Make = (Spec: Spec) => {
|
|
32
|
+
// Single owner of the disconnect schedule's rule name. Create and delete must
|
|
33
|
+
// derive it identically — they previously did not (create prefixed the stack,
|
|
34
|
+
// delete did not), so every delete targeted a name that was never created and
|
|
35
|
+
// the rule survived. The stack prefix itself is load-bearing: several stacks
|
|
36
|
+
// share one EventBridge bus, and an unprefixed plugin id would collide.
|
|
37
|
+
let disconnectScheduleName = id => Spec.environment ++ ("-" ++ id)
|
|
38
|
+
|
|
32
39
|
let forwardCommand = async (
|
|
33
40
|
_id,
|
|
34
41
|
command,
|
|
@@ -104,7 +111,7 @@ module Make = (Spec: Spec) => {
|
|
|
104
111
|
switch directive {
|
|
105
112
|
| PluginExtensionPointSpec.CreateDisconnectSchedule(id, timeout) =>
|
|
106
113
|
await createSchedule({
|
|
107
|
-
name:
|
|
114
|
+
name: id->disconnectScheduleName,
|
|
108
115
|
rate: timeout->ScheduleOps.minutesFromNow,
|
|
109
116
|
payload: {
|
|
110
117
|
Message.id,
|
|
@@ -114,7 +121,7 @@ module Make = (Spec: Spec) => {
|
|
|
114
121
|
->Message.encodeCommand'(S.string, PluginExtensionPointSpec.commandSchema)
|
|
115
122
|
->JSON.stringify,
|
|
116
123
|
})
|
|
117
|
-
| DeleteDisconnectSchedule(id) => await deleteSchedule(id)
|
|
124
|
+
| DeleteDisconnectSchedule(id) => await deleteSchedule(id->disconnectScheduleName)
|
|
118
125
|
| ForwardCommand({id, command, extensionPointName}) =>
|
|
119
126
|
await forwardCommand(id, command, extensionPointName, queryEngine)
|
|
120
127
|
| DoConnectPlugin(pluginDef) =>
|
|
@@ -23,6 +23,7 @@ function disconnectGrace(interval) {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
function Make(Spec) {
|
|
26
|
+
let disconnectScheduleName = id => Spec.environment + ("-" + id);
|
|
26
27
|
let forwardCommand = async (_id, command, extensionPointName, queryEngine) => {
|
|
27
28
|
let jsons = await queryEngine.scan(PluginSpec$ReventlessCore.name, [
|
|
28
29
|
[
|
|
@@ -81,7 +82,7 @@ function Make(Spec) {
|
|
|
81
82
|
case "CreateDisconnectSchedule" :
|
|
82
83
|
let id = directive._0;
|
|
83
84
|
return await createSchedule({
|
|
84
|
-
name:
|
|
85
|
+
name: disconnectScheduleName(id),
|
|
85
86
|
rate: ScheduleOps$ReventlessCore.minutesFromNow(directive._1),
|
|
86
87
|
payload: JSON.stringify(Message$ReventlessCore.encodeCommand$p({
|
|
87
88
|
id: id,
|
|
@@ -90,7 +91,7 @@ function Make(Spec) {
|
|
|
90
91
|
}, S.string, PluginExtensionPointSpec$ReventlessInfra.commandSchema))
|
|
91
92
|
});
|
|
92
93
|
case "DeleteDisconnectSchedule" :
|
|
93
|
-
return await deleteSchedule(directive._0);
|
|
94
|
+
return await deleteSchedule(disconnectScheduleName(directive._0));
|
|
94
95
|
case "DoConnectPlugin" :
|
|
95
96
|
let fn = Spec.manageSubscriptions;
|
|
96
97
|
if (fn !== undefined) {
|
|
@@ -355,6 +356,7 @@ function Make(Spec) {
|
|
|
355
356
|
mapOutgoingEvent: mapOutgoingEvent
|
|
356
357
|
});
|
|
357
358
|
return {
|
|
359
|
+
disconnectScheduleName: disconnectScheduleName,
|
|
358
360
|
forwardCommand: forwardCommand,
|
|
359
361
|
directiveHandler: directiveHandler,
|
|
360
362
|
PluginMapping: PluginMapping,
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Guards the disconnect schedule's rule name. Create and delete must derive it
|
|
2
|
+
// identically: they previously did not — create prefixed `Spec.environment`,
|
|
3
|
+
// delete did not — so every delete targeted a rule that had never been created
|
|
4
|
+
// and the real rule survived. The leak is invisible at runtime, because the
|
|
5
|
+
// delete reports success against a name AWS simply doesn't have.
|
|
6
|
+
|
|
7
|
+
open JestGlobals
|
|
8
|
+
|
|
9
|
+
let created: ref<array<string>> = ref([])
|
|
10
|
+
let deleted: ref<array<string>> = ref([])
|
|
11
|
+
|
|
12
|
+
module DisconnectSpec = {
|
|
13
|
+
let runtimeOps: PluginRuntimeOperations.operations = {
|
|
14
|
+
messagePublish: {
|
|
15
|
+
sendMessageToChannel: async (~channelId as _, ~messageBody as _) => (),
|
|
16
|
+
},
|
|
17
|
+
}
|
|
18
|
+
let environment = "teststack"
|
|
19
|
+
let updateApiSchema = None
|
|
20
|
+
let manageSubscriptions = None
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module EP = PluginExtensionPoint_Plugin.Make(DisconnectSpec)
|
|
24
|
+
|
|
25
|
+
let createSchedule: Reventless.Schedule.create = async schedule => {
|
|
26
|
+
created := created.contents->Array.concat([schedule.name])
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let deleteSchedule: Reventless.Schedule.delete = async name => {
|
|
30
|
+
deleted := deleted.contents->Array.concat([name])
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let queryEngine: Reventless.QueryEngine.operations = {
|
|
34
|
+
scan: async (~readModelName as _, ~filterConfigs as _, ~limit as _) => [],
|
|
35
|
+
query: async (
|
|
36
|
+
~readModelName as _,
|
|
37
|
+
~key as _=?,
|
|
38
|
+
~id as _,
|
|
39
|
+
~subIdConfig as _=?,
|
|
40
|
+
~filterConfigs as _=?,
|
|
41
|
+
~ascending as _=?,
|
|
42
|
+
~limit as _=?,
|
|
43
|
+
) => [],
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let pluginId = "Catalog_1.0.0-alpha.169"
|
|
47
|
+
|
|
48
|
+
let handle = directive => EP.directiveHandler(createSchedule, deleteSchedule, queryEngine, directive)
|
|
49
|
+
|
|
50
|
+
describe("plugin disconnect schedule", () => {
|
|
51
|
+
test("create and delete address the same rule name", async () => {
|
|
52
|
+
created := []
|
|
53
|
+
deleted := []
|
|
54
|
+
await handle(ReventlessInfra.PluginExtensionPointSpec.CreateDisconnectSchedule(pluginId, 5))
|
|
55
|
+
await handle(DeleteDisconnectSchedule(pluginId))
|
|
56
|
+
expect(deleted.contents)->toEqual(created.contents)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
test("the rule name is namespaced by stack", async () => {
|
|
60
|
+
created := []
|
|
61
|
+
await handle(ReventlessInfra.PluginExtensionPointSpec.CreateDisconnectSchedule(pluginId, 5))
|
|
62
|
+
// Several stacks share one EventBridge bus, so a bare plugin id would
|
|
63
|
+
// collide across them.
|
|
64
|
+
expect(created.contents)->toEqual(["teststack-" ++ pluginId])
|
|
65
|
+
})
|
|
66
|
+
})
|