nervur 0.7.1 → 0.7.5

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.
Files changed (4) hide show
  1. package/admin.mjs +10 -5
  2. package/being.mjs +61 -29
  3. package/ground.mjs +12 -11
  4. package/package.json +1 -1
package/admin.mjs CHANGED
@@ -4,7 +4,8 @@ const ADMIN = `({
4
4
  memory: { 'aliases/*': { type: 'String', class: 'data' } },
5
5
  interface: \`
6
6
  input RefInput { address: String!, nextPkHash: String, rights: String }
7
- type Census { stored: Int!, active: Int! }
7
+ type Resident { address: String!, alias: String, digest: String, active: Boolean! }
8
+ type Census { residents: [Resident!]!, stored: Int!, active: Int! }
8
9
  type Query {
9
10
  census: Census @rights(is: [SELF, MEMBER])
10
11
  aliasOf(name: String!): String @rights(is: [SELF, MEMBER])
@@ -23,10 +24,14 @@ const ADMIN = `({
23
24
  \`,
24
25
  resolvers: {
25
26
  Query: {
26
- census: (_, __, { registry }) => ({
27
- active: registry.active(),
28
- stored: registry.stored(),
29
- }),
27
+ census: (_, __, { registry }) => {
28
+ const residents = registry.residents();
29
+ return {
30
+ active: residents.filter((one) => one.active).length,
31
+ residents,
32
+ stored: residents.length,
33
+ };
34
+ },
30
35
  aliasOf: (_, { name }, { modules }) => modules.memory.read('aliases/' + name),
31
36
  attest: (_, { module }, { registry }) => registry.attest(module),
32
37
  opened: (_, __, { modules }) => modules.memory.list('refs/').length > 0,
package/being.mjs CHANGED
@@ -56,13 +56,13 @@ const rootFor = ({ memory, voice, address }) => {
56
56
  return opened === undefined ? undefined : Buffer.from(opened, 'base64');
57
57
  };
58
58
 
59
- const Port = ({ voice, mine, modules, rights }) => {
59
+ const Port = ({ voice, mine, deliver, rights }) => {
60
60
  const stamp = Stamp();
61
61
  const lanes = new Map();
62
62
  const send = async (to, op) => {
63
63
  const turn = (lanes.get(to) ?? Promise.resolve()).then(() => {
64
64
  const handle = mine.read(`handles/${to}`);
65
- return modules.deliver(
65
+ return deliver(
66
66
  Tools.envelope(handle === undefined ? voice : Voice.revive(handle.face), to, op, stamp()),
67
67
  );
68
68
  });
@@ -112,7 +112,7 @@ const rotates = ({ mine }, from, nextPkHash) => {
112
112
  return from;
113
113
  };
114
114
 
115
- const Being = ({ voice, address, modules, registry, vouched, watch }) => {
115
+ const Being = ({ voice, address, deliver, modules, registry, vouched, watch }) => {
116
116
  const memory = modules.memory;
117
117
  const root = rootFor({ memory, voice, address });
118
118
  const source = memory.read(address, 'program')?.value;
@@ -214,7 +214,7 @@ const Being = ({ voice, address, modules, registry, vouched, watch }) => {
214
214
  const asked = await program.ask({
215
215
  context: {
216
216
  modules: Object.freeze({ ...modules, memory: scoped(mine, program) }),
217
- port: Port({ voice, mine, modules, rights }),
217
+ port: Port({ voice, mine, deliver, rights }),
218
218
  registry,
219
219
  rights,
220
220
  },
@@ -257,6 +257,8 @@ const make = ({ memory, voice, address, program }) => {
257
257
  const Registry = ({
258
258
  memory,
259
259
  adminMine,
260
+ address,
261
+ deliver,
260
262
  modules,
261
263
  modulesFor,
262
264
  announce,
@@ -266,22 +268,28 @@ const Registry = ({
266
268
  watch,
267
269
  }) => {
268
270
  const live = new Map();
269
- const activate = (address) => {
270
- if (live.has(address)) {
271
- return live.get(address);
271
+ const activate = (at) => {
272
+ if (live.has(at)) {
273
+ return live.get(at);
272
274
  }
273
- const held = adminMine.read(`identity/custody/${address}`);
275
+ const held = adminMine.read(`identity/custody/${at}`);
274
276
  const voice = held === undefined ? undefined : Voice.revive(held);
275
277
  if (voice === undefined) {
276
278
  return undefined;
277
279
  }
278
- const door = Being({ voice, address, modules: modulesFor(voice), vouched, watch });
279
- live.set(address, door);
280
+ const door = Being({
281
+ address: at,
282
+ deliver,
283
+ modules: modulesFor(voice),
284
+ vouched,
285
+ voice,
286
+ watch,
287
+ });
288
+ live.set(at, door);
280
289
  return door;
281
290
  };
282
291
  return Object.freeze({
283
292
  activate,
284
- active: () => live.size,
285
293
  attest,
286
294
  create: ({ program, refs = [], data = {}, bindings, config } = {}) => {
287
295
  const written = program === undefined ? undefined : Program(program);
@@ -329,43 +337,67 @@ const Registry = ({
329
337
  announce(address);
330
338
  return address;
331
339
  },
332
- deactivate: (address) => live.delete(address),
333
- upgrade: ({ address, program }) => {
334
- const held = adminMine.read(`identity/custody/${address}`);
335
- const voice = held === undefined ? undefined : Voice.revive(held);
340
+ deactivate: (at) => live.delete(at),
341
+ upgrade: ({ address: target, program }) => {
336
342
  const written = program === undefined ? undefined : Program(program);
337
- if (voice === undefined || written === undefined) {
343
+ if (written === undefined) {
338
344
  return undefined;
339
345
  }
340
346
  const orphaned = memory
341
- .list(address, '')
342
- .filter((key) => memory.read(address, key)?.value !== null)
347
+ .list(target, '')
348
+ .filter((key) => memory.read(target, key)?.value !== null)
343
349
  .filter((key) => written.classOf(key) === undefined);
344
350
  if (orphaned.length > 0) {
345
351
  return undefined;
346
352
  }
353
+ if (target === address) {
354
+ return adminMine.write('program', program) === undefined ? undefined : target;
355
+ }
356
+ const held = adminMine.read(`identity/custody/${target}`);
357
+ const voice = held === undefined ? undefined : Voice.revive(held);
358
+ if (voice === undefined) {
359
+ return undefined;
360
+ }
347
361
  const claim = {
348
- address,
362
+ address: target,
349
363
  key: 'program',
350
364
  value: program,
351
- version: (memory.read(address, 'program')?.version ?? 0) + 1,
365
+ version: (memory.read(target, 'program')?.version ?? 0) + 1,
352
366
  };
353
367
  if (memory.write({ ...claim, sig: voice.sign(Tools.canon(claim)) }) === undefined) {
354
368
  return undefined;
355
369
  }
356
- live.delete(address);
357
- return address;
370
+ live.delete(target);
371
+ return target;
358
372
  },
359
- destroy: (address) => {
360
- if (adminMine.read(`identity/custody/${address}`) === undefined) {
373
+ destroy: (at) => {
374
+ if (adminMine.read(`identity/custody/${at}`) === undefined) {
361
375
  return undefined;
362
376
  }
363
- adminMine.write(`identity/custody/${address}`, undefined);
364
- live.delete(address);
365
- forget(address);
366
- return address;
377
+ adminMine.write(`identity/custody/${at}`, undefined);
378
+ live.delete(at);
379
+ forget(at);
380
+ return at;
381
+ },
382
+ residents: () => {
383
+ const aliasFor = new Map();
384
+ for (const key of adminMine.list('aliases/')) {
385
+ const named = adminMine.read(key);
386
+ if (typeof named === 'string') {
387
+ aliasFor.set(named, key.slice('aliases/'.length));
388
+ }
389
+ }
390
+ return adminMine.list('identity/custody/').map((key) => {
391
+ const at = key.slice('identity/custody/'.length);
392
+ const digest = Program(memory.read(at, 'program')?.value)?.digest ?? null;
393
+ return {
394
+ address: at,
395
+ alias: aliasFor.get(at) ?? null,
396
+ active: live.has(at),
397
+ digest,
398
+ };
399
+ });
367
400
  },
368
- stored: () => adminMine.list('identity/custody/').length,
369
401
  });
370
402
  };
371
403
 
package/ground.mjs CHANGED
@@ -94,10 +94,7 @@ const Ground = (modules = {}) => {
94
94
  {
95
95
  ...extra,
96
96
  ...boundFor(voice),
97
- deliver: (envelope) => deliver(envelope),
98
97
  memory,
99
- paths,
100
- wire,
101
98
  },
102
99
  Tools.address(voice.pk),
103
100
  ),
@@ -147,6 +144,8 @@ const Ground = (modules = {}) => {
147
144
  const registry = Registry({
148
145
  memory,
149
146
  adminMine,
147
+ address,
148
+ deliver: (envelope) => deliver(envelope),
150
149
  modules: adminModules,
151
150
  modulesFor,
152
151
  announce,
@@ -155,14 +154,16 @@ const Ground = (modules = {}) => {
155
154
  attest,
156
155
  watch,
157
156
  });
158
- const admin = Being({
159
- voice: adminVoice,
160
- address,
161
- modules: adminModules,
162
- registry,
163
- vouched,
164
- watch,
165
- });
157
+ const admin = (envelope, token) =>
158
+ Being({
159
+ address,
160
+ deliver: (envelope) => deliver(envelope),
161
+ modules: adminModules,
162
+ registry,
163
+ vouched,
164
+ voice: adminVoice,
165
+ watch,
166
+ })(envelope, token);
166
167
 
167
168
  announce(address);
168
169
  for (const key of adminMine.list('identity/custody/')) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nervur",
3
- "version": "0.7.1",
3
+ "version": "0.7.5",
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",