@reventlessdev/reventless-core 3.0.0-alpha.149 → 3.0.0-alpha.150
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 +7 -0
- package/package.json +6 -6
- package/src/components/Api/SuryToJsonSchema.res +5 -0
- package/src/components/Api/SuryToJsonSchema.res.mjs +4 -0
- package/src/plugin/lifecycle/PluginsReadModelSpec.res +3 -1
- package/src/plugin/lifecycle/PluginsReadModelSpec.res.mjs +1 -0
- package/tests/api/SuryToJsonSchemaTest.res +20 -0
- package/tests/api/SuryToJsonSchemaTest.res.mjs +51 -0
- package/tests/plugin/StateViewSlice/PsAnnotatedView.res.mjs +1 -0
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.150 (2026-07-10)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **reventless-ppx:** add [@group](https://github.com/group)By state-field annotation → x-reventless-group-by ([9e7a7b2](https://github.com/ReventlessDev/reventless-core/commit/9e7a7b29e54fb4eda1c6a145c0e7b6dcf26940ee))
|
|
11
|
+
|
|
12
|
+
|
|
6
13
|
# 3.0.0-alpha.149 (2026-07-09)
|
|
7
14
|
|
|
8
15
|
### Bug Fixes
|
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.150",
|
|
4
4
|
"description": "Core package for Reventless framework",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -29,21 +29,21 @@
|
|
|
29
29
|
"sury": "11.0.0-alpha.4",
|
|
30
30
|
"uuid": "^13.0.0",
|
|
31
31
|
"@reventlessdev/rescript-effect": "0.1.0-alpha.25",
|
|
32
|
+
"@reventlessdev/rescript-fast-csv": "1.2.0-alpha.11",
|
|
32
33
|
"@reventlessdev/rescript-hash-object": "1.2.0-alpha.10",
|
|
33
34
|
"@reventlessdev/rescript-jest": "1.0.0-alpha.6",
|
|
34
|
-
"@reventlessdev/rescript-fast-csv": "1.2.0-alpha.11",
|
|
35
35
|
"@reventlessdev/rescript-node-streams": "1.1.0-alpha.10",
|
|
36
36
|
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.14",
|
|
37
37
|
"@reventlessdev/rescript-ssh2": "1.1.0-alpha.11",
|
|
38
|
-
"@reventlessdev/reventless-infra": "3.0.0-alpha.91",
|
|
39
|
-
"@reventlessdev/reventless-spec": "3.0.0-alpha.69",
|
|
40
38
|
"@reventlessdev/rescript-uuid": "1.1.0-alpha.14",
|
|
41
|
-
"@reventlessdev/reventless-
|
|
39
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.92",
|
|
40
|
+
"@reventlessdev/reventless-interop": "3.0.0-alpha.24",
|
|
41
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.70"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"rescript": "^12.3.0",
|
|
45
45
|
"sury-ppx": "11.0.0-alpha.2",
|
|
46
|
-
"@reventlessdev/reventless-ppx": "1.0.0-alpha.
|
|
46
|
+
"@reventlessdev/reventless-ppx": "1.0.0-alpha.52"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"rescript": "^12.3.0"
|
|
@@ -44,6 +44,11 @@ let mergeAnnotations = (
|
|
|
44
44
|
if spec.summary->Array.includes(fieldName) {
|
|
45
45
|
obj->Dict.set("x-reventless-summary", JSON.Encode.bool(true))
|
|
46
46
|
}
|
|
47
|
+
switch spec.groupBy {
|
|
48
|
+
| Some(name) if name === fieldName =>
|
|
49
|
+
obj->Dict.set("x-reventless-group-by", JSON.Encode.bool(true))
|
|
50
|
+
| _ => ()
|
|
51
|
+
}
|
|
47
52
|
switch spec.drillTargets->Array.find(((field, _)) => field === fieldName) {
|
|
48
53
|
| Some((_, sliceName)) =>
|
|
49
54
|
obj->Dict.set("x-reventless-drillTarget", JSON.Encode.string(sliceName))
|
|
@@ -41,6 +41,10 @@ function mergeAnnotations(fieldSchema, fieldName, spec) {
|
|
|
41
41
|
if (spec.summary.includes(fieldName)) {
|
|
42
42
|
obj["x-reventless-summary"] = true;
|
|
43
43
|
}
|
|
44
|
+
let name = spec.groupBy;
|
|
45
|
+
if (name !== undefined && name === fieldName) {
|
|
46
|
+
obj["x-reventless-group-by"] = true;
|
|
47
|
+
}
|
|
44
48
|
let match$1 = spec.drillTargets.find(param => param[0] === fieldName);
|
|
45
49
|
if (match$1 !== undefined) {
|
|
46
50
|
obj["x-reventless-drillTarget"] = match$1[1];
|
|
@@ -42,7 +42,9 @@ type state = {
|
|
|
42
42
|
// @scan opts the field into server-side equality filtering so the connection gains
|
|
43
43
|
// a `kindEq` filter — the panel split (main list vs System/Infrastructure) pages
|
|
44
44
|
// correctly server-side rather than filtering a page client-side.
|
|
45
|
-
@
|
|
45
|
+
// @groupBy tags this field as the list view's section key (emitted as
|
|
46
|
+
// `x-reventless-group-by`); AutoUI sections the admin Plugins view by kind.
|
|
47
|
+
@scan @groupBy kind: Reventless.Plugin.pluginKind,
|
|
46
48
|
// Other versions of this name that are currently **Connected** — excludes this
|
|
47
49
|
// row's own `version` (whose status is the `status` field above). Lets the
|
|
48
50
|
// projection recompute which version is current (highest Connected) during a
|
|
@@ -30,6 +30,7 @@ let emptySpec: Reventless.StateAnnotations.stateAnnotationSpec = {
|
|
|
30
30
|
scan: [],
|
|
31
31
|
scanSort: [],
|
|
32
32
|
status: None,
|
|
33
|
+
groupBy: None,
|
|
33
34
|
visibility: None,
|
|
34
35
|
}
|
|
35
36
|
|
|
@@ -305,6 +306,25 @@ describe("SuryToJsonSchema:", () => {
|
|
|
305
306
|
))->toEqual((Some(true), None))
|
|
306
307
|
})
|
|
307
308
|
|
|
309
|
+
testSync("emits x-reventless-group-by on the field named by groupBy", () => {
|
|
310
|
+
let schema = S.schema(s =>
|
|
311
|
+
{
|
|
312
|
+
"id": s.matches(S.string),
|
|
313
|
+
"kind": s.matches(S.string),
|
|
314
|
+
}
|
|
315
|
+
)->S.castToUnknown
|
|
316
|
+
let schema' = schema->withSpec({...emptySpec, groupBy: Some("kind")})
|
|
317
|
+
let json = SuryToJsonSchema.deriveObjectSchema(schema')
|
|
318
|
+
let kindSchema = getPropertyOf(json, "kind")
|
|
319
|
+
let idSchema = getPropertyOf(json, "id")
|
|
320
|
+
expect((
|
|
321
|
+
kindSchema
|
|
322
|
+
->Option.flatMap(s => getProperty(s, "x-reventless-group-by"))
|
|
323
|
+
->Option.flatMap(JSON.Decode.bool),
|
|
324
|
+
idSchema->Option.flatMap(s => getProperty(s, "x-reventless-group-by")),
|
|
325
|
+
))->toEqual((Some(true), None))
|
|
326
|
+
})
|
|
327
|
+
|
|
308
328
|
testSync("emits x-reventless-collapsed on field listed in collapsed", () => {
|
|
309
329
|
let schema = S.schema(s =>
|
|
310
330
|
{
|
|
@@ -64,6 +64,7 @@ let emptySpec = {
|
|
|
64
64
|
scan: emptySpec_scan,
|
|
65
65
|
scanSort: emptySpec_scanSort,
|
|
66
66
|
status: undefined,
|
|
67
|
+
groupBy: undefined,
|
|
67
68
|
visibility: undefined
|
|
68
69
|
};
|
|
69
70
|
|
|
@@ -100,6 +101,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
100
101
|
scan: emptySpec_scan,
|
|
101
102
|
scanSort: emptySpec_scanSort,
|
|
102
103
|
status: undefined,
|
|
104
|
+
groupBy: undefined,
|
|
103
105
|
visibility: undefined
|
|
104
106
|
});
|
|
105
107
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -129,6 +131,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
129
131
|
scan: emptySpec_scan,
|
|
130
132
|
scanSort: emptySpec_scanSort,
|
|
131
133
|
status: undefined,
|
|
134
|
+
groupBy: undefined,
|
|
132
135
|
visibility: undefined
|
|
133
136
|
});
|
|
134
137
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -161,6 +164,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
161
164
|
scan: emptySpec_scan,
|
|
162
165
|
scanSort: emptySpec_scanSort,
|
|
163
166
|
status: undefined,
|
|
167
|
+
groupBy: undefined,
|
|
164
168
|
visibility: undefined
|
|
165
169
|
});
|
|
166
170
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -189,6 +193,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
189
193
|
scan: emptySpec_scan,
|
|
190
194
|
scanSort: emptySpec_scanSort,
|
|
191
195
|
status: undefined,
|
|
196
|
+
groupBy: undefined,
|
|
192
197
|
visibility: undefined
|
|
193
198
|
});
|
|
194
199
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -217,6 +222,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
217
222
|
scan: emptySpec_scan,
|
|
218
223
|
scanSort: emptySpec_scanSort,
|
|
219
224
|
status: undefined,
|
|
225
|
+
groupBy: undefined,
|
|
220
226
|
visibility: undefined
|
|
221
227
|
});
|
|
222
228
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -242,6 +248,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
242
248
|
scan: emptySpec_scan,
|
|
243
249
|
scanSort: emptySpec_scanSort,
|
|
244
250
|
status: undefined,
|
|
251
|
+
groupBy: undefined,
|
|
245
252
|
visibility: undefined
|
|
246
253
|
});
|
|
247
254
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -267,6 +274,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
267
274
|
scan: emptySpec_scan,
|
|
268
275
|
scanSort: emptySpec_scanSort,
|
|
269
276
|
status: undefined,
|
|
277
|
+
groupBy: undefined,
|
|
270
278
|
visibility: undefined
|
|
271
279
|
});
|
|
272
280
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -299,6 +307,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
299
307
|
scan: emptySpec_scan,
|
|
300
308
|
scanSort: emptySpec_scanSort,
|
|
301
309
|
status: undefined,
|
|
310
|
+
groupBy: undefined,
|
|
302
311
|
visibility: undefined
|
|
303
312
|
});
|
|
304
313
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -334,6 +343,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
334
343
|
scan: emptySpec_scan,
|
|
335
344
|
scanSort: emptySpec_scanSort,
|
|
336
345
|
status: undefined,
|
|
346
|
+
groupBy: undefined,
|
|
337
347
|
visibility: undefined
|
|
338
348
|
});
|
|
339
349
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -372,6 +382,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
372
382
|
scan: emptySpec_scan,
|
|
373
383
|
scanSort: emptySpec_scanSort,
|
|
374
384
|
status: undefined,
|
|
385
|
+
groupBy: undefined,
|
|
375
386
|
visibility: undefined
|
|
376
387
|
});
|
|
377
388
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -400,6 +411,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
400
411
|
scan: emptySpec_scan,
|
|
401
412
|
scanSort: emptySpec_scanSort,
|
|
402
413
|
status: undefined,
|
|
414
|
+
groupBy: undefined,
|
|
403
415
|
visibility: undefined
|
|
404
416
|
});
|
|
405
417
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -425,6 +437,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
425
437
|
scan: ["status"],
|
|
426
438
|
scanSort: emptySpec_scanSort,
|
|
427
439
|
status: undefined,
|
|
440
|
+
groupBy: undefined,
|
|
428
441
|
visibility: undefined
|
|
429
442
|
});
|
|
430
443
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -457,6 +470,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
457
470
|
scan: emptySpec_scan,
|
|
458
471
|
scanSort: ["name"],
|
|
459
472
|
status: undefined,
|
|
473
|
+
groupBy: undefined,
|
|
460
474
|
visibility: undefined
|
|
461
475
|
});
|
|
462
476
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -470,6 +484,39 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
470
484
|
undefined
|
|
471
485
|
]);
|
|
472
486
|
});
|
|
487
|
+
globalThis.test("emits x-reventless-group-by on the field named by groupBy", () => {
|
|
488
|
+
let schema = S.schema(s => ({
|
|
489
|
+
id: s.m(S.string),
|
|
490
|
+
kind: s.m(S.string)
|
|
491
|
+
}));
|
|
492
|
+
let schema$p = withSpec(schema, {
|
|
493
|
+
ids: emptySpec_ids,
|
|
494
|
+
compositeIds: emptySpec_compositeIds,
|
|
495
|
+
subIds: emptySpec_subIds,
|
|
496
|
+
compositeSubIds: emptySpec_compositeSubIds,
|
|
497
|
+
indexes: emptySpec_indexes,
|
|
498
|
+
hidden: emptySpec_hidden,
|
|
499
|
+
summary: emptySpec_summary,
|
|
500
|
+
drillTargets: emptySpec_drillTargets,
|
|
501
|
+
drillTargetKeys: emptySpec_drillTargetKeys,
|
|
502
|
+
collapsed: emptySpec_collapsed,
|
|
503
|
+
scan: emptySpec_scan,
|
|
504
|
+
scanSort: emptySpec_scanSort,
|
|
505
|
+
status: undefined,
|
|
506
|
+
groupBy: "kind",
|
|
507
|
+
visibility: undefined
|
|
508
|
+
});
|
|
509
|
+
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
510
|
+
let kindSchema = getPropertyOf(json, "kind");
|
|
511
|
+
let idSchema = getPropertyOf(json, "id");
|
|
512
|
+
globalThis.expect([
|
|
513
|
+
Stdlib_Option.flatMap(Stdlib_Option.flatMap(kindSchema, s => getProperty(s, "x-reventless-group-by")), Stdlib_JSON.Decode.bool),
|
|
514
|
+
Stdlib_Option.flatMap(idSchema, s => getProperty(s, "x-reventless-group-by"))
|
|
515
|
+
]).toEqual([
|
|
516
|
+
true,
|
|
517
|
+
undefined
|
|
518
|
+
]);
|
|
519
|
+
});
|
|
473
520
|
globalThis.test("emits x-reventless-collapsed on field listed in collapsed", () => {
|
|
474
521
|
let schema = S.schema(s => ({
|
|
475
522
|
id: s.m(S.string),
|
|
@@ -489,6 +536,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
489
536
|
scan: emptySpec_scan,
|
|
490
537
|
scanSort: emptySpec_scanSort,
|
|
491
538
|
status: undefined,
|
|
539
|
+
groupBy: undefined,
|
|
492
540
|
visibility: undefined
|
|
493
541
|
});
|
|
494
542
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -520,6 +568,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
520
568
|
scan: emptySpec_scan,
|
|
521
569
|
scanSort: emptySpec_scanSort,
|
|
522
570
|
status: undefined,
|
|
571
|
+
groupBy: undefined,
|
|
523
572
|
visibility: "Internal"
|
|
524
573
|
});
|
|
525
574
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -543,6 +592,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
543
592
|
scan: emptySpec_scan,
|
|
544
593
|
scanSort: emptySpec_scanSort,
|
|
545
594
|
status: undefined,
|
|
595
|
+
groupBy: undefined,
|
|
546
596
|
visibility: undefined
|
|
547
597
|
});
|
|
548
598
|
let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema$p);
|
|
@@ -606,6 +656,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
|
|
|
606
656
|
scan: emptySpec_scan,
|
|
607
657
|
scanSort: emptySpec_scanSort,
|
|
608
658
|
status: undefined,
|
|
659
|
+
groupBy: undefined,
|
|
609
660
|
visibility: undefined
|
|
610
661
|
});
|
|
611
662
|
let native = S.toJSONSchema(schema$p);
|