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

Proposal to reduce circular dependency headaches #174

Open
RonaldZielaznicki opened this issue Nov 3, 2023 · 0 comments
Open

Proposal to reduce circular dependency headaches #174

RonaldZielaznicki opened this issue Nov 3, 2023 · 0 comments

Comments

@RonaldZielaznicki
Copy link

RonaldZielaznicki commented Nov 3, 2023

Context

It often happens that an object model needs to reference itself or a model that references it. There exists a work around for this in the FAQ; but I think there are some problems that exist with the work around. Namely while working across file or modules.

Context - FAQ Example

import { ObjectModel } from 'objectmodel' 

const Honey = ObjectModel({
   sweetie: undefined // Sweetie is not yet defined
});

const Sweetie = ObjectModel({
   honey: Honey
});

Honey.definition.sweetie = [Sweetie];

Context - Modules example

honey.js

import { ObjectModel } from 'objectmodel' 

const Honey = ObjectModel({
   sweetie: undefined // Sweetie is not yet defined
});

sweetie.js

import { ObjectModel } from 'objectmodel' 
import { Honey } from './honey.js';

export const Sweetie = ObjectModel({
   honey: Honey
});

index.js

import { Honey } from './honey.js'
import { Sweetie } from './sweetie.js'

Honey.definition.sweetie = [Sweetie];

const joe = Honey({ sweetie: undefined }); // ann is not yet defined
const ann = Sweetie({ honey: joe });
joe.sweetie = ann;

Context - Issues

  • It is only safe to use Honey's definition in index.js. Importing directly from honey.js could end with an incorrect model definition if index.js is not imported elsewhere.
  • It hides part of Honey's definition in another file without anything to point a developer towards it. We could add a comment here pointing someone to the definition, but that has some problems too. Like if the file moved.
  • We could move Honey's definition of sweetie into honey.js, but then we have to deal with a circular import.

Proposal

Introduce a RefModel that allows you to reference a Model indirectly.

RefModels would resolve to their proper definition later when a model is turned into an instance. Ideally, this would happen once and work as a regular definition from then on.

Proposal - Example

honey.js

import { ObjectModel, RefModel } from 'objectmodel' 

export const Honey = ObjectModel({
  sweetie: RefModel('Sweetie')
}).as('Honey')

sweetie.js

import { ObjectModel, RefModel } from 'objectmodel' 

export const Sweetie = ObjectModel({
  honey: RefModel('Honey')
}).as('Sweetie')

index.js

import { Honey } from './honey.js'
import { Sweetie } from './sweetie.js'

const joe = Honey({ sweetie: undefined }); // ann is not yet defined
// Here is where Sweetie's definition for .honey would finalize.
const ann = Sweetie({ honey: joe });
// Here is where Honey's's definition for .sweetie would finalize.
joe.sweetie = ann;


// Definitions were finalized already, so there should be less overhead when creating
// instances of Sweetie and Honey for chelsea and bob.
const chelsea = Sweetie({ honey: undefined });
const bob = Honey({ sweetie: chelsea });
chelsea.honey = bob;

Other thoughts

using .as

I'm not married to the idea of utilizing .as with reference models. It seemed the easier path, but I could see problems coming in for it's original use case; which is to name the model for debugging. For instance, name collisions if two models are declared with the same string passed to .as.

Could add a new method, to get the job done. Maybe .ref? It could throw an error on a name collision.

Allowing RefModels to be undefined

In the proposal example, joe is instantiated with sweetie as undefined. As is, that might end in an error unless RefModels also allow themselves to be undefined.

The work to implement the change

Additionally, I'd be willing to implement the changes myself and submit a PR if you're into the idea. Might need a little direction, but otherwise am willing

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