@reventlessdev/reventless-aws 3.0.0-alpha.322 → 3.0.0-alpha.323

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.323 (2026-08-23)
7
+
8
+ ### Bug Fixes
9
+
10
+ * **querydb:** serve the previous page instead of refusing it ([48341c9](https://github.com/ReventlessDev/reventless-core/commit/48341c9f61b5155b441deeb0edc9abf461948346))
11
+
12
+
6
13
  # 3.0.0-alpha.322 (2026-08-23)
7
14
 
8
15
  ### Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/reventless-aws",
3
- "version": "3.0.0-alpha.322",
3
+ "version": "3.0.0-alpha.323",
4
4
  "description": "AWS adapters for Reventless",
5
5
  "license": "Apache-2.0",
6
6
  "bin": {
@@ -16,17 +16,17 @@
16
16
  "sury": "11.0.0-rc.2",
17
17
  "uuid": "^13.0.0",
18
18
  "@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.13",
19
- "@reventlessdev/rescript-jest": "1.0.0-alpha.10",
20
- "@reventlessdev/rescript-effect": "0.1.0-alpha.32",
21
19
  "@reventlessdev/rescript-node": "2.0.0-alpha.8",
22
- "@reventlessdev/rescript-pulumi-aws": "3.0.0-alpha.4",
20
+ "@reventlessdev/rescript-effect": "0.1.0-alpha.32",
21
+ "@reventlessdev/rescript-pulumi-aws": "3.0.0-alpha.5",
22
+ "@reventlessdev/rescript-jest": "1.0.0-alpha.10",
23
23
  "@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.19",
24
- "@reventlessdev/reventless-core": "3.0.0-alpha.249",
25
- "@reventlessdev/reventless-infra": "3.0.0-alpha.151",
26
24
  "@reventlessdev/rescript-uuid": "2.0.0-alpha.0",
27
25
  "@reventlessdev/reventless-interop": "3.0.0-alpha.33",
28
- "@reventlessdev/reventless-postgres": "3.0.0-alpha.113",
29
- "@reventlessdev/reventless-spec": "3.0.0-alpha.123"
26
+ "@reventlessdev/reventless-postgres": "3.0.0-alpha.114",
27
+ "@reventlessdev/reventless-core": "3.0.0-alpha.250",
28
+ "@reventlessdev/reventless-spec": "3.0.0-alpha.123",
29
+ "@reventlessdev/reventless-infra": "3.0.0-alpha.151"
30
30
  },
31
31
  "devDependencies": {
32
32
  "rescript": "12.3.0",
@@ -51,16 +51,32 @@ describe("listAllItemsConnection — paging", () => {
51
51
  })
52
52
 
53
53
  testSync("a filtered read examines more rows than it serves", () => {
54
- expect(code->String.includes("parts.length > 0 ? (_first > 1000 ? _first : 1000)"))->toBe(true)
55
- expect(code->String.includes("const _page = _rest.slice(0, _first);"))->toBe(true)
54
+ // The budget reads as deep as the page needs, which for a backward cut is
55
+ // `_upTo` rather than `_first + _from`.
56
+ expect(
57
+ code->String.includes("parts.length > 0 ? ((_backward ? _upTo : _first + _from) > 1000"),
58
+ )->toBe(true)
59
+ expect(code->String.includes("const _page = _backward ? _rest : _rest.slice(0, _first);"))
60
+ ->toBe(true)
56
61
  expect(code->String.includes("hasNextPage: _more || !!_next,"))->toBe(true)
57
62
  })
58
63
 
59
- testSync("backward paging (last/before) is rejected, not silently mishandled", () => {
60
- expect(code->String.includes("ctx.args.before != null || ctx.args.last != null"))->toBe(true)
64
+ // `before` is served by re-reading the window the cursor names; only a previous
65
+ // page lying in an EARLIER window is out of reach, and `last` which needs the
66
+ // end of the list — stays refused.
67
+ testSync("backward paging is served, and its one limit is named", () => {
68
+ expect(code->String.includes("ctx.args.before != null && ctx.args.before !== ''"))->toBe(true)
69
+ expect(code->String.includes("_backward && _upTo <= 0 && _window !== null"))->toBe(true)
61
70
  expect(code->String.includes("UnsupportedPagination"))->toBe(true)
62
71
  })
63
72
 
73
+ // The door must not advertise a previous page it cannot serve — that is what
74
+ // put a live Prev button in front of an error.
75
+ testSync("only a reachable previous page is advertised", () => {
76
+ expect(code->String.includes("hasPreviousPage: _from > 0,"))->toBe(true)
77
+ expect(code->String.includes("hasPreviousPage: !!ctx.args.after,"))->toBe(false)
78
+ })
79
+
64
80
  testSync("a window emptied by the filter still yields a resumable boundary cursor", () => {
65
81
  expect(
66
82
  code->String.includes(
@@ -37,14 +37,19 @@ globalThis.describe("listAllItemsConnection — paging", () => {
37
37
  globalThis.expect(code.includes("ctx.args.after + '_' + i")).toBe(false);
38
38
  });
39
39
  globalThis.test("a filtered read examines more rows than it serves", () => {
40
- globalThis.expect(code.includes("parts.length > 0 ? (_first > 1000 ? _first : 1000)")).toBe(true);
41
- globalThis.expect(code.includes("const _page = _rest.slice(0, _first);")).toBe(true);
40
+ globalThis.expect(code.includes("parts.length > 0 ? ((_backward ? _upTo : _first + _from) > 1000")).toBe(true);
41
+ globalThis.expect(code.includes("const _page = _backward ? _rest : _rest.slice(0, _first);")).toBe(true);
42
42
  globalThis.expect(code.includes("hasNextPage: _more || !!_next,")).toBe(true);
43
43
  });
44
- globalThis.test("backward paging (last/before) is rejected, not silently mishandled", () => {
45
- globalThis.expect(code.includes("ctx.args.before != null || ctx.args.last != null")).toBe(true);
44
+ globalThis.test("backward paging is served, and its one limit is named", () => {
45
+ globalThis.expect(code.includes("ctx.args.before != null && ctx.args.before !== ''")).toBe(true);
46
+ globalThis.expect(code.includes("_backward && _upTo <= 0 && _window !== null")).toBe(true);
46
47
  globalThis.expect(code.includes("UnsupportedPagination")).toBe(true);
47
48
  });
49
+ globalThis.test("only a reachable previous page is advertised", () => {
50
+ globalThis.expect(code.includes("hasPreviousPage: _from > 0,")).toBe(true);
51
+ globalThis.expect(code.includes("hasPreviousPage: !!ctx.args.after,")).toBe(false);
52
+ });
48
53
  globalThis.test("a window emptied by the filter still yields a resumable boundary cursor", () => {
49
54
  globalThis.expect(code.includes("const _boundary = _next ? util.base64Encode(JSON.stringify({ t: _next, n: -1 })) : null;")).toBe(true);
50
55
  globalThis.expect(code.includes("edges.length > 0 ? edges[edges.length - 1].cursor : _boundary")).toBe(true);