Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions packages/tempo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,25 +64,31 @@ deno add npm:@magmacomputing/tempo # deno
```

<details>
<summary><b>🌐 Browser & Lite Environments</b></summary>
<summary><b>🌐 Browser & Native Environments</b></summary>

For standard usage natively in the browser, use the pre-optimized **Global ESM Bundle**. It includes the entire core engine in a single file:

For modern browsers using **Import Maps**:
```html
<script type="importmap">
{
"imports": {
"@magmacomputing/tempo": "https://cdn.jsdelivr.net/npm/@magmacomputing/tempo@2/dist/tempo.bundle.esm.js"
"@js-temporal/polyfill": "https://cdn.jsdelivr.net/npm/@js-temporal/polyfill@0.5.1/dist/index.esm.js",
"@magmacomputing/tempo": "https://cdn.jsdelivr.net/npm/@magmacomputing/tempo@3/dist/tempo.bundle.esm.js"
}
}
</script>
```

For rapid prototyping without a package manager (UMD):
```html
<script src="https://cdn.jsdelivr.net/npm/@magmacomputing/tempo@2/dist/tempo.bundle.js"></script>
<script type="module">
import '@js-temporal/polyfill';
import { Tempo } from '@magmacomputing/tempo';

const t = new Tempo('next Friday');
</script>
```

For granular "Lite" builds, see the [Full Installation Guide](https://magmacomputing.github.io/magma/doc/installation).
> **Advanced Usage (Plugins & CDNs)**
> If you need to use **Tempo Premium Plugins** natively in the browser, require granular module resolution, or want to use on-the-fly bundling CDNs (like `esm.sh`), please see our comprehensive [**Browser Installation Guide**](./doc/installation.md) for detailed import map configurations.

</details>

---
Expand Down
79 changes: 70 additions & 9 deletions packages/tempo/doc/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,27 +93,28 @@ const t = new Tempo();

---

## 🌐 Browser (Modern ESM)
## 🌐 Browser & Native Environments

For browser environments that support **Import Maps**, you can use the granular ESM modules. This is the recommended way to use Tempo in the browser as it allows for better caching and modularity.
Tempo provides multiple native browser distribution formats. Here is the quick breakdown of which approach to use:
- **Standard Usage** (No plugins): Use the Global Bundle.
- **Plugins without a bundler**: Use **esm.sh** (Easiest) OR use Granular Import Maps (Hardest, but maximum control).
- **Plugins with a bundler** (Vite/Webpack): Do nothing. Your bundler handles the resolution automatically.

### 1. Import Map Setup
Add this to your `<head>` to resolve the dependencies:
### 1. The Global Bundle (Standard Usage)

> Note: If you are self-hosting Tempo files, use the shipped `packages/tempo/importmap.json` as-is for your installed version instead of hand-authoring `dist/` paths.
The easiest way to use Tempo natively in the browser is via the pre-optimized ESM bundle. It includes the entire core engine in a single file, eliminating network waterfall effects.

```html
<script type="importmap">
{
"imports": {
"@js-temporal/polyfill": "https://cdn.jsdelivr.net/npm/@js-temporal/polyfill@0.5/dist/index.esm.js",
"@js-temporal/polyfill": "https://cdn.jsdelivr.net/npm/@js-temporal/polyfill@0.5.1/dist/index.esm.js",
"@magmacomputing/tempo": "https://cdn.jsdelivr.net/npm/@magmacomputing/tempo@3/dist/tempo.bundle.esm.js"
}
}
</script>
```

### 2. Implementation
```html
<script type="module">
import '@js-temporal/polyfill';
Expand All @@ -124,15 +125,75 @@ Add this to your `<head>` to resolve the dependencies:
</script>
```

### 2. Smart CDNs (The "Best-of-Both-Worlds")

If you want to use **Premium Plugins** natively in the browser *without* configuring the massive granular import map required by static CDNs, use an on-the-fly bundling CDN like [esm.sh](https://esm.sh). It reads the package resolution rules and bundles the complex internal dependencies automatically.

While you *could* import directly from the URL everywhere, the best practice is to use a tiny, simple import map just for your top-level packages. This allows you to keep your actual application code clean and standard:

```html
<!-- 1. A tiny import map for your clean shortcuts -->
<script type="importmap">
{
"imports": {
"@magmacomputing/tempo": "https://esm.sh/@magmacomputing/tempo@3.0.1",
"@magmacomputing/tempo-plugin-ticker": "https://esm.sh/@magmacomputing/tempo-plugin-ticker@1.0.4"
}
}
</script>

<!-- 2. Your Application Code -->
<script type="module">
// You can use standard bare specifiers thanks to the tiny import map above.
// esm.sh handles all the complex internal plugin routing behind the scenes!
import { Tempo } from '@magmacomputing/tempo';
import { TickerModule } from '@magmacomputing/tempo-plugin-ticker';

Tempo.extend(TickerModule);
</script>
```

### 3. Granular ESM (Advanced Plugin Architecture)

If you are strictly using a static CDN (like jsdelivr) and require Premium Plugins, you must use the Granular ESM distribution. The bundled engine drops internal builder-utilities to keep the global scope clean, but plugins require them to resolve their own dependencies.

To use Premium Plugins via static CDN, you must map the core library, its subpaths, and the internal licensing module directly to their granular equivalents:

```html
<script type="importmap">
{
"imports": {
"tslib": "https://cdn.jsdelivr.net/npm/tslib@2.8.1/tslib.es6.mjs",
"@js-temporal/polyfill": "https://cdn.jsdelivr.net/npm/@js-temporal/polyfill@0.5.1/dist/index.esm.js",

"@magmacomputing/tempo": "https://cdn.jsdelivr.net/npm/@magmacomputing/tempo@3.0.1/dist/tempo.index.js",
"@magmacomputing/tempo/core": "https://cdn.jsdelivr.net/npm/@magmacomputing/tempo@3.0.1/dist/core.index.js",
"@magmacomputing/tempo/library": "https://cdn.jsdelivr.net/npm/@magmacomputing/tempo@3.0.1/dist/library.index.js",
"@magmacomputing/tempo/plugin": "https://cdn.jsdelivr.net/npm/@magmacomputing/tempo@3.0.1/dist/plugin/plugin.index.js",
"@magmacomputing/tempo/enums": "https://cdn.jsdelivr.net/npm/@magmacomputing/tempo@3.0.1/dist/support/support.enum.js",
"@magmacomputing/tempo/term": "https://cdn.jsdelivr.net/npm/@magmacomputing/tempo@3.0.1/dist/plugin/term/term.index.js",

"#tempo/license": "https://cdn.jsdelivr.net/npm/@magmacomputing/tempo@3.0.1/dist/plugin/license/license.validator.js",

"@magmacomputing/tempo-plugin-astro": "https://cdn.jsdelivr.net/npm/@magmacomputing/tempo-plugin-astro@1.1.6/dist/index.js",
"@magmacomputing/tempo-plugin-ticker": "https://cdn.jsdelivr.net/npm/@magmacomputing/tempo-plugin-ticker@1.0.4/dist/index.js"
}
}
</script>
```

> [!WARNING] Cache Busting
> The jsdelivr CDN aggressively caches major version tags (like `@3`). When relying on precise granular resolution for plugins, it is highly recommended to use explicit patch versions (like `@3.0.1`) to avoid fetching mismatched or outdated sub-modules.

---

## 📦 Browser (Legacy / Global Bundle)
## 📦 Browser (UMD / Global Variable)

If you aren't using ESM or just want a simple `<script>` tag for rapid prototyping, use the UMD global bundle. This attaches `Tempo` to the `window` object.

```html
<!-- Load the Temporal Polyfill first -->
<script src="https://cdn.jsdelivr.net/npm/@js-temporal/polyfill@0.5/dist/index.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@js-temporal/polyfill@0.5.1/dist/index.umd.js"></script>

<!-- Load the Tempo Global Bundle -->
<script src="https://cdn.jsdelivr.net/npm/@magmacomputing/tempo@3/dist/tempo.bundle.js"></script>
Expand Down
6 changes: 5 additions & 1 deletion packages/tempo/importmap.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
{
"_comment": "This JSON is the sanctioned browser import map for this package. Entries using './dist/...' MUST resolve relative to where this JSON is hosted (typically alongside the package's dist folder). Note that '#tempo/license' is an internal/private specifier used at runtime, which is why it differs from the public '@magmacomputing/' exports.",
"imports": {
"tslib": "https://cdn.jsdelivr.net/npm/tslib@2.8.1/tslib.es6.mjs",
"@js-temporal/polyfill": "https://cdn.jsdelivr.net/npm/@js-temporal/polyfill@0.5/dist/index.esm.js",
"@magmacomputing/tempo": "https://cdn.jsdelivr.net/npm/@magmacomputing/tempo@3/dist/tempo.bundle.esm.js",
"@magmacomputing/tempo/core": "./dist/core.index.js",
"@magmacomputing/tempo/duration": "./dist/module/module.duration.js",
"@magmacomputing/tempo/mutate": "./dist/module/module.mutate.js",
"@magmacomputing/tempo/plugin": "./dist/plugin/plugin.index.js",
"@magmacomputing/tempo/library": "./dist/library.index.js"
"@magmacomputing/tempo/library": "./dist/library.index.js",
"@magmacomputing/tempo/enums": "./dist/support/support.enum.js",
"#tempo/license": "./dist/plugin/license/license.validator.js"
}
}
Loading