Replace boundary structure to preserve embedded value separation
This commit is contained in:
parent
9521fc3dcc
commit
40f5ef4085
|
@ -2,22 +2,22 @@
|
||||||
/// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
/// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
||||||
|
|
||||||
import * as S from '../gen/sturdy.js';
|
import * as S from '../gen/sturdy.js';
|
||||||
import { Decoder, DecoderState, Encoder, EncoderState, GenericEmbedded, neverEmbeddedType, EmbeddedType, Value, EmbeddedWriter } from '@preserves/core';
|
import { Decoder, DecoderState, Encoder, EncoderState, GenericEmbedded, neverEmbeddedType, EmbeddedType, Value, Embedded, EmbeddedWriter } from '@preserves/core';
|
||||||
|
|
||||||
export const wireRefEmbeddedType: EmbeddedType<S.WireRef> & EmbeddedWriter<S.WireRef> = {
|
export const wireRefEmbeddedType: EmbeddedType<Embedded<S.WireRef>> & EmbeddedWriter<Embedded<S.WireRef>> = {
|
||||||
decode(s: DecoderState): S.WireRef {
|
decode(s: DecoderState): Embedded<S.WireRef> {
|
||||||
return S.asWireRef(new Decoder<any>(s).next());
|
return new Embedded<S.WireRef>(S.asWireRef(new Decoder<any>(s).next()));
|
||||||
},
|
},
|
||||||
|
|
||||||
encode(s: EncoderState, v: S.WireRef): void {
|
encode(s: EncoderState, v: Embedded<S.WireRef>): void {
|
||||||
new Encoder<any>(s, neverEmbeddedType).push(S.fromWireRef(v));
|
new Encoder<any>(s, neverEmbeddedType).push(S.fromWireRef(v.value));
|
||||||
},
|
},
|
||||||
|
|
||||||
fromValue(v: Value<GenericEmbedded>): S.WireRef {
|
fromValue(v: Value<GenericEmbedded>): Embedded<S.WireRef> {
|
||||||
return S.asWireRef(v as Value<S._embedded>);
|
return new Embedded<S.WireRef>(S.asWireRef(v as Value<S._embedded>));
|
||||||
},
|
},
|
||||||
|
|
||||||
toValue(v: S.WireRef): Value<GenericEmbedded> {
|
toValue(v: Embedded<S.WireRef>): Value<GenericEmbedded> {
|
||||||
return S.fromWireRef(v) as Value<GenericEmbedded>;
|
return S.fromWireRef(v.value) as Value<GenericEmbedded>;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
/// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
||||||
|
|
||||||
import { Actor, Assertion, Entity, Facet, Handle, Ref, Turn } from '../runtime/actor.js';
|
import { Actor, Assertion, Entity, Facet, Handle, Ref, Turn } from '../runtime/actor.js';
|
||||||
import { BytesLike, Decoder, Dictionary, encode, IdentityMap, mapEmbeddeds, stringify, underlying, Value } from '@preserves/core';
|
import { BytesLike, Decoder, Dictionary, encode, IdentityMap, mapEmbeddeds, Embedded, stringify, underlying, Value } from '@preserves/core';
|
||||||
import * as IO from '../gen/protocol.js';
|
import * as IO from '../gen/protocol.js';
|
||||||
import { wireRefEmbeddedType } from './protocol.js';
|
import { wireRefEmbeddedType } from './protocol.js';
|
||||||
import { attenuate } from '../runtime/rewrite.js';
|
import { attenuate } from '../runtime/rewrite.js';
|
||||||
|
@ -68,7 +68,7 @@ export class RelayEntity implements Entity {
|
||||||
this.oid = oid;
|
this.oid = oid;
|
||||||
}
|
}
|
||||||
|
|
||||||
send(m: IO.Event<WireRef>): void {
|
send(m: IO.Event<Embedded<WireRef>>): void {
|
||||||
this.relay.send(this.oid, m);
|
this.relay.send(this.oid, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ export class Relay {
|
||||||
readonly imported = new Membrane();
|
readonly imported = new Membrane();
|
||||||
readonly peer: Ref | null;
|
readonly peer: Ref | null;
|
||||||
nextLocalOid: IO.Oid = 0;
|
nextLocalOid: IO.Oid = 0;
|
||||||
pendingTurn: IO.Turn<WireRef> = [];
|
pendingTurn: IO.Turn<Embedded<WireRef>> = [];
|
||||||
debug: boolean;
|
debug: boolean;
|
||||||
trustPeer: boolean;
|
trustPeer: boolean;
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ export class Relay {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.peer = (options.initialOid !== void 0)
|
this.peer = (options.initialOid !== void 0)
|
||||||
? this.rewriteRefIn(WireRef.mine(options.initialOid), [])
|
? this.rewriteRefIn(new Embedded<WireRef>(WireRef.mine(options.initialOid)), [])
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
if (options.nextLocalOid !== void 0) {
|
if (options.nextLocalOid !== void 0) {
|
||||||
|
@ -188,9 +188,9 @@ export class Relay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
register(targetRemoteOid: IO.Oid, assertion: Assertion, handle: Handle): Value<WireRef>;
|
register(targetRemoteOid: IO.Oid, assertion: Assertion, handle: Handle): Value<Embedded<WireRef>>;
|
||||||
register(targetRemoteOid: null, assertion: Assertion, handle: null): Value<WireRef>;
|
register(targetRemoteOid: null, assertion: Assertion, handle: null): Value<Embedded<WireRef>>;
|
||||||
register(targetRemoteOid: IO.Oid | null, assertion: Assertion, handle: Handle | null): Value<WireRef> {
|
register(targetRemoteOid: IO.Oid | null, assertion: Assertion, handle: Handle | null): Value<Embedded<WireRef>> {
|
||||||
const transient = (handle === null);
|
const transient = (handle === null);
|
||||||
const pins: Array<WireSymbol> = [];
|
const pins: Array<WireSymbol> = [];
|
||||||
const rewritten = mapEmbeddeds(assertion, r => this.rewriteRefOut(r, transient, pins));
|
const rewritten = mapEmbeddeds(assertion, r => this.rewriteRefOut(r, transient, pins));
|
||||||
|
@ -223,18 +223,18 @@ export class Relay {
|
||||||
return e.ref;
|
return e.ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
rewriteRefOut(r: Ref, transient: boolean, pins: Array<WireSymbol>): WireRef {
|
rewriteRefOut(r: Ref, transient: boolean, pins: Array<WireSymbol>): Embedded<WireRef> {
|
||||||
if (r.target instanceof RelayEntity && r.target.relay === this) {
|
if (r.target instanceof RelayEntity && r.target.relay === this) {
|
||||||
if (r.attenuation === void 0 || r.attenuation.length === 0) {
|
if (r.attenuation === void 0 || r.attenuation.length === 0) {
|
||||||
// No extra conditions on this reference since it was sent to us.
|
// No extra conditions on this reference since it was sent to us.
|
||||||
this.grabImportedOid(r.target.oid, pins);
|
this.grabImportedOid(r.target.oid, pins);
|
||||||
return WireRef.yours({ oid: r.target.oid, attenuation: [] });
|
return new Embedded<WireRef>(WireRef.yours({ oid: r.target.oid, attenuation: [] }));
|
||||||
} else {
|
} else {
|
||||||
// This reference has been attenuated since it was sent to us.
|
// This reference has been attenuated since it was sent to us.
|
||||||
// Do we trust the peer to enforce such attenuation on our behalf?
|
// Do we trust the peer to enforce such attenuation on our behalf?
|
||||||
if (this.trustPeer) {
|
if (this.trustPeer) {
|
||||||
this.grabImportedOid(r.target.oid, pins);
|
this.grabImportedOid(r.target.oid, pins);
|
||||||
return WireRef.yours({ oid: r.target.oid, attenuation: r.attenuation });
|
return new Embedded<WireRef>(WireRef.yours({ oid: r.target.oid, attenuation: r.attenuation }));
|
||||||
} else {
|
} else {
|
||||||
// fall through: treat the attenuated ref as a local ref, and re-export it.
|
// fall through: treat the attenuated ref as a local ref, and re-export it.
|
||||||
}
|
}
|
||||||
|
@ -247,10 +247,11 @@ export class Relay {
|
||||||
return new WireSymbol(this.exported, this.nextLocalOid++, r);
|
return new WireSymbol(this.exported, this.nextLocalOid++, r);
|
||||||
});
|
});
|
||||||
pins.push(e);
|
pins.push(e);
|
||||||
return WireRef.mine(e.oid);
|
return new Embedded<WireRef>(WireRef.mine(e.oid));
|
||||||
}
|
}
|
||||||
|
|
||||||
rewriteRefIn(n: WireRef, pins: Array<WireSymbol>): Ref {
|
rewriteRefIn(nw: Embedded<WireRef>, pins: Array<WireSymbol>): Ref {
|
||||||
|
const n = nw.value;
|
||||||
switch (n._variant) {
|
switch (n._variant) {
|
||||||
case 'yours': {
|
case 'yours': {
|
||||||
const e = this.exported.grab("byOid", n.oid, false, null);
|
const e = this.exported.grab("byOid", n.oid, false, null);
|
||||||
|
@ -283,7 +284,7 @@ export class Relay {
|
||||||
|
|
||||||
message(body: Assertion) {
|
message(body: Assertion) {
|
||||||
if (body === FLUSH) {
|
if (body === FLUSH) {
|
||||||
if (this.debug) console.log('OUT', stringify(IO.fromTurn(this.pendingTurn)));
|
if (this.debug) console.log('OUT', stringify(IO.fromTurn(this.pendingTurn)), this.pendingTurn);
|
||||||
this.w(underlying(encode(IO.fromTurn(this.pendingTurn), {
|
this.w(underlying(encode(IO.fromTurn(this.pendingTurn), {
|
||||||
canonical: true,
|
canonical: true,
|
||||||
embeddedEncode: wireRefEmbeddedType,
|
embeddedEncode: wireRefEmbeddedType,
|
||||||
|
@ -292,7 +293,7 @@ export class Relay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send(remoteOid: IO.Oid, m: IO.Event<WireRef>): void {
|
send(remoteOid: IO.Oid, m: IO.Event<Embedded<WireRef>>): void {
|
||||||
if (this.pendingTurn.length === 0) {
|
if (this.pendingTurn.length === 0) {
|
||||||
Turn.active.message(this.selfRef, FLUSH);
|
Turn.active.message(this.selfRef, FLUSH);
|
||||||
}
|
}
|
||||||
|
@ -313,14 +314,14 @@ export class Relay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
rewriteIn(a: Value<WireRef>): [Assertion, Array<WireSymbol>]
|
rewriteIn(a: Value<Embedded<WireRef>>): [Assertion, Array<WireSymbol>]
|
||||||
{
|
{
|
||||||
const pins: Array<WireSymbol> = [];
|
const pins: Array<WireSymbol> = [];
|
||||||
const rewritten = mapEmbeddeds(a, r => this.rewriteRefIn(r, pins));
|
const rewritten = mapEmbeddeds(a, r => this.rewriteRefIn(r, pins));
|
||||||
return [rewritten, pins];
|
return [rewritten, pins];
|
||||||
}
|
}
|
||||||
|
|
||||||
handle(localOid: IO.Oid, m: IO.Event<WireRef>) {
|
handle(localOid: IO.Oid, m: IO.Event<Embedded<WireRef>>) {
|
||||||
switch (m._variant) {
|
switch (m._variant) {
|
||||||
case 'Assert': {
|
case 'Assert': {
|
||||||
const [a, pins] = this.rewriteIn(m.value.assertion);
|
const [a, pins] = this.rewriteIn(m.value.assertion);
|
||||||
|
|
Loading…
Reference in New Issue