-
Notifications
You must be signed in to change notification settings - Fork 0
Library Packages
In our move to using package.json for our widget libraries, we need to consider some issues with how the library packages are constructed. Maqetta can read a library if it contains both widget metadata and maqetta metadata. However, a library may not always come with metadata (i.e. see the current content of the Dojo Foundation Registry). For that reason, Maqetta must be allowed to load a library and its metadata from different sources.
In order to accomplish this, we'll need to allow the creation of packages for metadata, with dependencies on the library package. A library and metadata can come in 3 distinct package configurations:
- A package for the library + widget metadata + Maqetta metadata.
- One package for the library + widget metadata; one package for the Maqetta metadata.
- One package for the library; one package for the widget metadata; one package for the Maqetta metadta.
Package layout:
+ package.json
+ library/
+-- main.js
+ metadata
|-- library/
| +-- main_oam.json
+-- widgets.json
*-- themes/
+-- classic.theme
package.json:
{
"name": "library",
...
"directories": {
"lib": "library"
},
...
"overlays": {
"oam": {
"directories": {
"metadata": "metadata/library"
}
},
"maqetta": {
"directories": {
"theme_metadata": "metadata/themes"
},
"scripts": {
"widget_metadata": "metadata/widgets.json"
}
}
}
}
package layout:
+ package.json
+ library/
+-- main.js
+ metadata
+-- library/
+-- main_oam.json
package.json:
{
"name": "library",
"version": "v1.0",
...
"directories": {
"lib": "library"
},
...
"overlays": {
"oam": {
"directories": {
"metadata": "metadata/library"
}
}
}
}
package layout:
+ package.json
+ metadata
+-- widgets.json
*-- themes/
+-- classic.theme
package.json:
{
"name": "library-maq",
...
"dependencies": {
"library": "v1.0"
},
...
"overlays": {
"maqetta": {
"directories": {
"theme_metadata": "metadata/themes"
},
"scripts": {
"widget_metadata": "metadata/widgets.json"
}
}
}
}
package layout:
+ package.json
+ library/
+-- main.js
package.json:
{
"name": "library",
"version": "v1.0"
...
"directories": {
"lib": "library"
}
}
package layout:
+ package.json
+ metadata
+-- library/
+-- main_oam.json
package.json:
{
"name": "library-oam",
"version": "v1.0",
...
"dependencies": {
"library": "v1.0"
},
...
"overlays": {
"oam": {
"directories": {
"metadata": "metadata/library"
}
}
}
}
package layout:
+ package.json
+ metadata
+-- widgets.json
*-- themes/
+-- classic.theme
package.json:
{
"name": "library-maq",
...
"dependencies": {
"library": {
"library-oam": "v1.0",
"library": "v1.0"
}
},
...
"overlays": {
"maqetta": {
"directories": {
"theme_metadata": "metadata/themes"
},
"scripts": {
"widget_metadata": "metadata/widgets.json"
}
}
}
}
Notice the dependencies
structure for the Maqetta metadata package in scenario 3. The Packages spec allows a 'dependencies' to be a hash, wherein the order determines priority (see references below).
In this case, a client loading the Maqetta metadata package will first try to satisfy its library
dependency with "library-oam", followed by "library". The first dependency ("library-oam") is satisfied by the widget metadata package in scenario 3. However, if that package isn't available, the Maqetta metadata package also lists "library" as the next dependency. This one is actually satisfied by the 'library + widget metadata' package specified in scenario 2.
The Packages 1.0 Spec says,
Package managers and loaders should ignore unknown fields in the package descriptor file.
The UncommonJS Packages spec states,
Any properties of
package.json
not specified here must occur under an "overlays" mapping.
For that reason, I have chosen to specify the OAM and widgets.json locations inside of overlays
properties.
An algorithm for loading library packages from with Maqetta may look something like this:
- iterate over library packages
- read package file, doing a mixin for "oam" and "maqetta" overlays
- if package DOES NOT contain `scripts.widget_metadata`, ignore
- load package dependencies
- if simple dep, immediately load
- if complex dep, iterate over list of deps and
- if current dep is available, use it
- if not, continue to next dep
- if any dep is not found, ignore package
This should allow for the packages to come from different locations. For example, it is conceivable that a library package may come from one location, but the metadata package(s) may be listed elsewhere.
- The
dependencies
element was indeed meant to allow a "choice" of dependencies, and the order was explicit, even though the dependencies choice is specified as an object hash (instead of array). Thinking went that most implimentations keep object order (even though not in spec) and that ES5 did spec object hash order.