@stonyx/orm 0.3.2-alpha.59 → 0.3.2-alpha.60
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/dist/setup-rest-server.js +32 -8
- package/package.json +1 -1
- package/src/setup-rest-server.ts +32 -8
|
@@ -45,17 +45,41 @@ export default async function (route, accessPath, metaRoute) {
|
|
|
45
45
|
// predicate -- which is what abofs/stonyx-orm#196 and #207 need in order to
|
|
46
46
|
// ask model X's predicate about a request routed to model Y.
|
|
47
47
|
//
|
|
48
|
-
// Published BEFORE `waitForModule('rest-server')
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
//
|
|
48
|
+
// Published BEFORE `await waitForModule('rest-server')`, deliberately: that
|
|
49
|
+
// await is the ONLY yield point in this function, and the rest-server module
|
|
50
|
+
// may already be listening by the time it reports ready, so an assignment
|
|
51
|
+
// after it would leave a window in which a route is live and the registry is
|
|
52
|
+
// not.
|
|
53
|
+
//
|
|
54
|
+
// It is NOT before the mount loop for that reason, and the comment here used
|
|
55
|
+
// to say it was. `RestServer.mountRoute` is fully synchronous -- construct,
|
|
56
|
+
// registerCalls(), api.use() -- and nothing between the loop and this
|
|
57
|
+
// function's closing brace yields, so the event loop cannot deliver a request
|
|
58
|
+
// in there and the window that clause described cannot open. Measured:
|
|
59
|
+
// moving this assignment to the last statement of the function leaves the
|
|
60
|
+
// suite at 951 pass / 0 fail. Being ahead of the mount loop is free and
|
|
61
|
+
// harmless; it is not what makes the ordering correct.
|
|
52
62
|
//
|
|
53
63
|
// Assigned unconditionally, including when the try above failed and the map
|
|
54
64
|
// is empty or partial: the mount loop below is driven by this exact object,
|
|
55
|
-
// so
|
|
56
|
-
// set of predicates that is
|
|
57
|
-
//
|
|
58
|
-
//
|
|
65
|
+
// so at the moment of assignment whatever is reachable through
|
|
66
|
+
// `Orm.instance` is the same set of predicates that is about to enforce.
|
|
67
|
+
// A guard such as `if (Object.keys(accessFunctions).length)` would let the
|
|
68
|
+
// registry go silently missing on a total load failure, and a later consumer
|
|
69
|
+
// would read `undefined` from `getAccess` and have to distinguish "no access
|
|
70
|
+
// class" from "the registry was never published" -- which it cannot. That is
|
|
71
|
+
// the reasoning, and it is REASONING, not something this suite tests: the
|
|
72
|
+
// guarded variant is also 951 pass / 0 fail, AC8 included, because every boot
|
|
73
|
+
// in this suite loads a non-empty access map so the guard never fires. AC8
|
|
74
|
+
// demonstrably cannot catch it. Catching it needs a boot with
|
|
75
|
+
// `orm.paths.access` pointed at an empty directory, which this suite has no
|
|
76
|
+
// harness for.
|
|
77
|
+
//
|
|
78
|
+
// One further limit on "by construction": the mount loop passes `access` BY
|
|
79
|
+
// VALUE into each OrmRequest, so the enforcing set is a snapshot taken here,
|
|
80
|
+
// while `getAccess` reads the map live. The two are the same set at boot and
|
|
81
|
+
// stay the same set only for as long as nobody writes to the public field.
|
|
82
|
+
// The equality is a boot-time fact, not an invariant.
|
|
59
83
|
Orm.instance.accessFunctions = accessFunctions;
|
|
60
84
|
await waitForModule('rest-server');
|
|
61
85
|
// Remove "/" prefix and name mount point accordingly
|
package/package.json
CHANGED
package/src/setup-rest-server.ts
CHANGED
|
@@ -57,17 +57,41 @@ export default async function(route: string, accessPath: string, metaRoute: bool
|
|
|
57
57
|
// predicate -- which is what abofs/stonyx-orm#196 and #207 need in order to
|
|
58
58
|
// ask model X's predicate about a request routed to model Y.
|
|
59
59
|
//
|
|
60
|
-
// Published BEFORE `waitForModule('rest-server')
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
//
|
|
60
|
+
// Published BEFORE `await waitForModule('rest-server')`, deliberately: that
|
|
61
|
+
// await is the ONLY yield point in this function, and the rest-server module
|
|
62
|
+
// may already be listening by the time it reports ready, so an assignment
|
|
63
|
+
// after it would leave a window in which a route is live and the registry is
|
|
64
|
+
// not.
|
|
65
|
+
//
|
|
66
|
+
// It is NOT before the mount loop for that reason, and the comment here used
|
|
67
|
+
// to say it was. `RestServer.mountRoute` is fully synchronous -- construct,
|
|
68
|
+
// registerCalls(), api.use() -- and nothing between the loop and this
|
|
69
|
+
// function's closing brace yields, so the event loop cannot deliver a request
|
|
70
|
+
// in there and the window that clause described cannot open. Measured:
|
|
71
|
+
// moving this assignment to the last statement of the function leaves the
|
|
72
|
+
// suite at 951 pass / 0 fail. Being ahead of the mount loop is free and
|
|
73
|
+
// harmless; it is not what makes the ordering correct.
|
|
64
74
|
//
|
|
65
75
|
// Assigned unconditionally, including when the try above failed and the map
|
|
66
76
|
// is empty or partial: the mount loop below is driven by this exact object,
|
|
67
|
-
// so
|
|
68
|
-
// set of predicates that is
|
|
69
|
-
//
|
|
70
|
-
//
|
|
77
|
+
// so at the moment of assignment whatever is reachable through
|
|
78
|
+
// `Orm.instance` is the same set of predicates that is about to enforce.
|
|
79
|
+
// A guard such as `if (Object.keys(accessFunctions).length)` would let the
|
|
80
|
+
// registry go silently missing on a total load failure, and a later consumer
|
|
81
|
+
// would read `undefined` from `getAccess` and have to distinguish "no access
|
|
82
|
+
// class" from "the registry was never published" -- which it cannot. That is
|
|
83
|
+
// the reasoning, and it is REASONING, not something this suite tests: the
|
|
84
|
+
// guarded variant is also 951 pass / 0 fail, AC8 included, because every boot
|
|
85
|
+
// in this suite loads a non-empty access map so the guard never fires. AC8
|
|
86
|
+
// demonstrably cannot catch it. Catching it needs a boot with
|
|
87
|
+
// `orm.paths.access` pointed at an empty directory, which this suite has no
|
|
88
|
+
// harness for.
|
|
89
|
+
//
|
|
90
|
+
// One further limit on "by construction": the mount loop passes `access` BY
|
|
91
|
+
// VALUE into each OrmRequest, so the enforcing set is a snapshot taken here,
|
|
92
|
+
// while `getAccess` reads the map live. The two are the same set at boot and
|
|
93
|
+
// stay the same set only for as long as nobody writes to the public field.
|
|
94
|
+
// The equality is a boot-time fact, not an invariant.
|
|
71
95
|
Orm.instance.accessFunctions = accessFunctions;
|
|
72
96
|
|
|
73
97
|
await waitForModule('rest-server');
|