Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A design for struct module identity #59

Open
guybedford opened this issue Nov 23, 2024 · 0 comments
Open

A design for struct module identity #59

guybedford opened this issue Nov 23, 2024 · 0 comments

Comments

@guybedford
Copy link

I know this has been discussed before and @nicolo-ribaudo has had some conversations here but I wanted to put this down in a clear issue. As we've been working through a lot of module identity questions in https://github.com/tc39/proposal-esm-phase-imports, we've landed at a place where it's now fully confirmed and specified how these designs support module cloning and identity across agents.

So I wanted to share that very simple design for how this might relate to struct identity. This is just a conceptual model for discussion as an alternative to https://github.com/tc39/proposal-structs/blob/main/ATTACHING-BEHAVIOR.md that replaces registration and naming with a module registry and export.

The starting point is that we can identify a struct using module identity by ensuring a fixed declaration of the shared struct in the module. And then providing a way to reference the execution and reference.

We do that using the module system by treating registered structs as a new form of export declaration:

export struct mystruct {
}

This new "export struct declaration" form would then create a strong 1-1 link between the struct and its declaring module. That is, the struct identity is the { module, exportName } pair, where module identity as specified in ESM Source Phase can then be used to complete the identity model.

To do this, the struct maintains a reference to its module internally by having the Struct Record include a [[Module]] field which points to the Module Record of the module it was defined by.

We could then take the following steps on postMessage(structObject):

  • Serialize the shared struct (per struct spec)
    • This would in turn, do a serialization of the [[Module]] field on the shared struct (if present for shared structs), per the ESM Phase Imports spec
  • Deserialize the struct on the other side
    • This would in turn, do a structured deserialization of the [[Module]] field on the other side, per the ESM Phase Imports spec.
    • Then it would apply import(deserializedModule) again per ESM Phase Imports ability to import module objects
    • Then it would simply do ns.mystruct to get the struct object
    • Provided that module and all its dependencies executed correctly, we now have a reference to the same conceptual struct on the other side

In summary, since the struct holds a reference to a module, cloning the struct means cloning the module and then picking up that reference again.

Cloning of modules under ESM Phase Imports has the following properties:

  • A cloned module always represents the exact same source text on the other side
  • Dependency modules in the registry are shared
  • Identity is shared so that cloning the same module multiple times results in unification of that module identity in the registry provided the module key (URL) and source (per ESM Phase Imports spec) are the same

So the properties of this design above would be exactly the desired properties for shared structs, while allowing library dependencies to be fully shared on their native realms (eg a import 'react' on one side translates to an import 'react' on the other side by registry naming conventions).

I believe this therefore satisfies the desired design constraints. Happy to discuss further as well anytime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant