@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 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.149",
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-interop": "3.0.0-alpha.24"
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.51"
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
- @scan kind: Reventless.Plugin.pluginKind,
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
@@ -48,6 +48,7 @@ let stateSchema$1 = S.Metadata.set(stateSchema, StateAnnotations$Reventless.stat
48
48
  scan: ["kind"],
49
49
  scanSort: [],
50
50
  status: undefined,
51
+ groupBy: "kind",
51
52
  visibility: undefined
52
53
  });
53
54
 
@@ -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);
@@ -65,6 +65,7 @@ let stateSchema$1 = S.Metadata.set(stateSchema, StateAnnotations$Reventless.stat
65
65
  scan: [],
66
66
  scanSort: [],
67
67
  status: undefined,
68
+ groupBy: undefined,
68
69
  visibility: undefined
69
70
  });
70
71