nervur 0.7.5 → 0.8.0

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/being.mjs CHANGED
@@ -39,15 +39,53 @@ const Compartment = ({ memory, voice, address, root, classOf }) => {
39
39
  });
40
40
  };
41
41
 
42
+ const offered = (modules, program, mine) =>
43
+ Object.freeze({
44
+ ...Object.fromEntries(
45
+ (program?.modules ?? [])
46
+ .map((one) => one.module)
47
+ .filter((name) => name !== 'memory' && modules[name] !== undefined)
48
+ .map((name) => [name, modules[name]]),
49
+ ),
50
+ memory: scoped(mine, program),
51
+ });
52
+
53
+ const grantable = (program) =>
54
+ (program?.rights ?? [...STRUCTURAL, 'MEMBER']).filter((one) => !STRUCTURAL.includes(one));
55
+
56
+ const referable = (mine, key, plain, program) => {
57
+ const rights = plain.rights ?? 'MEMBER';
58
+ if (!grantable(program).includes(rights)) {
59
+ return undefined;
60
+ }
61
+ if (key.startsWith('refs/pending/')) {
62
+ return { ...plain, rights };
63
+ }
64
+ const held = mine.read(key);
65
+ return {
66
+ ...plain,
67
+ nextPkHash: plain.nextPkHash ?? held?.nextPkHash ?? null,
68
+ rights,
69
+ seen: Math.max(plain.seen ?? 0, held?.seen ?? 0),
70
+ };
71
+ };
72
+
42
73
  const scoped = (mine, program) =>
43
74
  Object.freeze({
44
75
  classOf: mine.classOf,
45
76
  list: mine.list,
46
77
  read: mine.read,
47
- write: (key, plain) =>
48
- key.startsWith('refs/') || key.startsWith('handles/') || program?.declares(key) !== undefined
78
+ write: (key, plain) => {
79
+ if (key.startsWith('refs/') && plain !== undefined) {
80
+ const guarded = referable(mine, key, plain, program);
81
+ return guarded === undefined ? undefined : mine.write(key, guarded);
82
+ }
83
+ return key.startsWith('refs/') ||
84
+ key.startsWith('handles/') ||
85
+ program?.declares(key) !== undefined
49
86
  ? mine.write(key, plain)
50
- : undefined,
87
+ : undefined;
88
+ },
51
89
  });
52
90
 
53
91
  const rootFor = ({ memory, voice, address }) => {
@@ -213,7 +251,8 @@ const Being = ({ voice, address, deliver, modules, registry, vouched, watch }) =
213
251
  }
214
252
  const asked = await program.ask({
215
253
  context: {
216
- modules: Object.freeze({ ...modules, memory: scoped(mine, program) }),
254
+ from: program.caller ? from : undefined,
255
+ modules: offered(modules, program, mine),
217
256
  port: Port({ voice, mine, deliver, rights }),
218
257
  registry,
219
258
  rights,
@@ -305,7 +344,7 @@ const Registry = ({
305
344
  if (written !== undefined && (brought === undefined || settings === undefined)) {
306
345
  return undefined;
307
346
  }
308
- const allowed = written?.rights ?? [...STRUCTURAL, 'MEMBER'];
347
+ const allowed = grantable(written);
309
348
  if (refs.some((ref) => !allowed.includes(ref.rights ?? 'MEMBER'))) {
310
349
  return undefined;
311
350
  }
package/blueprint.mjs CHANGED
@@ -247,6 +247,7 @@ const Blueprint = (source) => {
247
247
  resolvers: resolverSources(written.resolvers ?? {}),
248
248
  }),
249
249
  ),
250
+ caller: needs.caller === true,
250
251
  memory: Object.freeze(memory),
251
252
  modules,
252
253
  name: written.name,
package/ground.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ADMIN } from './admin.mjs';
2
2
  import { Being, Compartment, Registry, make, rootFor } from './being.mjs';
3
- import { coreClass } from './blueprint.mjs';
3
+ import { Blueprint, coreClass } from './blueprint.mjs';
4
4
  import { Client } from './client.mjs';
5
5
  import { Contracts } from './contract.mjs';
6
6
  import { Memory, Paths, Wire } from './modules.mjs';
@@ -13,6 +13,22 @@ const GROUND = 'Ground';
13
13
 
14
14
  const FLOOR = ['blueprints', 'cells', 'contracts', 'keychain', 'paths', 'watch', 'wire'];
15
15
 
16
+ const doorsOf = (source) => {
17
+ const written = Blueprint(source);
18
+ if (written === undefined) {
19
+ return undefined;
20
+ }
21
+ return [written.schema.getQueryType(), written.schema.getMutationType()]
22
+ .filter((one) => one !== undefined && one !== null)
23
+ .flatMap((one) => Object.keys(one.getFields()));
24
+ };
25
+
26
+ const redefines = (source) => {
27
+ const custom = doorsOf(source);
28
+ const standard = doorsOf(ADMIN);
29
+ return custom === undefined || custom.some((one) => standard.includes(one));
30
+ };
31
+
16
32
  const install = ({ cells, keychain, program }) => {
17
33
  const memory = Memory(cells);
18
34
  const voice = Voice();
@@ -41,7 +57,11 @@ const Ground = (modules = {}) => {
41
57
  return undefined;
42
58
  }
43
59
 
44
- const program = modules.blueprints?.ground() ?? ADMIN;
60
+ const extension = modules.blueprints?.ground();
61
+ if (extension !== undefined && redefines(extension)) {
62
+ return undefined;
63
+ }
64
+ const program = extension ?? ADMIN;
45
65
  if (cells.peek('ground/admin') === undefined) {
46
66
  install({ cells, keychain, program });
47
67
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nervur",
3
- "version": "0.7.5",
3
+ "version": "0.8.0",
4
4
  "description": "A distributed system of sovereign beings — one door, one question: by whose authority.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Razvan Gherghina",
package/program.mjs CHANGED
@@ -52,6 +52,7 @@ const Program = (source) => {
52
52
  return answered.errors === undefined ? { data: answered.data } : undefined;
53
53
  },
54
54
  bindings: blueprint.bindings,
55
+ caller: blueprint.caller,
55
56
  classOf: blueprint.classOf,
56
57
  config: blueprint.config,
57
58
  declares: blueprint.declares,