Skip to content
Javier Pedemonte edited this page Nov 20, 2011 · 10 revisions

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.

1. Single package for library & metadata

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"
			}
		}
	}
}

2. Package for library & widget metadata, another for Maqetta metadata

Library and widget metadata

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"
			}
		}
	}
}

Maqetta metadata

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"
			}
		}
	}
}

3. Individual packages for library, widget metadata and Maqetta metadata

Library

package layout:

+ package.json
+ library/
   +-- main.js

package.json:

{
	"name": "library",
	"version": "v1.0"
	...
	"directories": {
		"lib": "library"
	}
}

Widget metadata

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"
			}
		}
	}
}

Maqetta metadata

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"
			}
		}
	}
}

Choice of Dependencies

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.

Overlays

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.

Library Package Loading Algorithm

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.

References

Packages 1.0 Specification

Packages 1.1 Proposal

Mappings/C Proposal

UncommonJs Packages spec

Packages 0.1 discussion

  • 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.
Clone this wiki locally