### Complete Glimmer.js Minimum Environment Setup
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/embedding/02-minimum-environment.md
This comprehensive example demonstrates the complete setup for a minimum Glimmer.js environment, including compilation, rendering, and execution.
```typescript
import { Component, Context } from '@glimmer/opcode-compiler';
import { artifacts } from '@glimmer/program';
import { precompile } from '@glimmer/compiler';
import createHTMLDocument from '@simple-dom/document';
import { AotRuntime, renderAot } from '@glimmer/runtime';
let source = `{{#let "hello" "world" as |hello world|}}
{{hello}} {{world}}
{{/let}}`;
let context = Context();
let component = Compilable(source);
let handle = component.compile(context);
let program = artifacts(context);
let document = createHTMLDocument();
let runtime = AotRuntime(document, payload);
let element = document.createElement('main');
let cursor = { element, nextSibling: null };
let iterator = renderAot(runtime, handle, cursor);
let result = iterator.sync();
function Compilable(source: string): CompilableProgram {
return Component(precompile(source));
}
```
--------------------------------
### Start Development Server
Source: https://github.com/emberjs/ember.js/blob/main/smoke-tests/app-template/README.md
Starts the development server and makes the application accessible at http://localhost:4200.
```bash
npm run start
```
--------------------------------
### Install Dependencies
Source: https://github.com/emberjs/ember.js/blob/main/smoke-tests/app-template/README.md
Run this command after cloning the repository to install all necessary project dependencies.
```bash
npm install
```
--------------------------------
### Start Development Server
Source: https://github.com/emberjs/ember.js/blob/main/CONTRIBUTING.md
Start the Ember.js development server to view tests in the browser.
```bash
pnpm start
```
--------------------------------
### Install Dependencies and Run Tests
Source: https://github.com/emberjs/ember.js/blob/main/CONTRIBUTING.md
Install project dependencies and run all unit tests. This is a prerequisite for submitting pull requests.
```bash
pnpm install && pnpm test
```
--------------------------------
### Autotracked Rendering Example
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/reactivity/autotracked-rendering.md
Demonstrates how to use `@tracked` properties and Glimmer components for reactive UI updates. This setup allows for automatic re-rendering when a tracked property changes.
```gjs
import { tracked } from '@glimmer/tracking';
class ModuleState {
@tracked count = 0;
increment() {
this.count++;
}
}
const state = new ModuleState();
```
--------------------------------
### Import and Start Ember Tests
Source: https://github.com/emberjs/ember.js/blob/main/smoke-tests/v2-app-template/tests/index.html
Imports the ember-testing module and the start function from './test-helper'. It also uses import.meta.glob to eagerly load all test files and then calls start() to initiate the test suite.
```javascript
import "ember-testing";
import { start } from './test-helper';
import.meta.glob("./**/*.{js,ts,gjs,gts}", { eager: true });
start();
```
--------------------------------
### Format CHANGELOG Entry
Source: https://github.com/emberjs/ember.js/blob/main/RELEASE.md
Example of how to format a CHANGELOG entry for a specific version and date.
```markdown
## v5.11.0 (August 15, 2023)
```
--------------------------------
### Install @glimmer/component
Source: https://github.com/emberjs/ember.js/blob/main/packages/@glimmer/component/README.md
Add the @glimmer/component package to your project's development dependencies.
```bash
npm install --save-dev @glimmer/component
```
--------------------------------
### Host Independent Example Template
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/embedding/02-minimum-environment.md
A Handlebars template demonstrating the `let` helper to define and use local variables. This example is host-agnostic and serves as a basic unit for embedding.
```handlebars
{{#let "hello" "world" as |hello world|}}
{{hello}} {{world}}
{{/let}}
```
--------------------------------
### Minimal Glimmer Environment Setup
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/embedding/03-adding-state.md
This code sets up a basic Glimmer environment for rendering a simple component. It includes necessary imports and compilation steps.
```ts
import { Component, Context } from '@glimmer/opcode-compiler';
import { precompile } from '@glimmer/compiler';
import createHTMLDocument from '@simple-dom/document';
import { AotRuntime, renderAot } from '@glimmer/runtime';
import Serializer from '@simple-dom/serializer';
import voidMap from '@simple-dom/void-map';
let source = `{{#let "hello" "world" as |hello world|}}
{{hello}} {{world}}
{{/let}}`;
let context = Context();
let component = Component(precompile(source));
let handle = component.compile(context);
let program = artifacts(context);
let document = createHTMLDocument();
let runtime = AotRuntime(document, payload);
let element = document.createElement('main');
let cursor = { element, nextSibling: null };
let iterator = renderAot(runtime, handle, cursor);
let result = iterator.sync();
console.log(serialize(element)); //
hello world
function serialize(element: SimpleElement): string {
return new Serializer(voidMap).serialize(element);
}
function Compilable(source: string): CompilableProgram {
return Component(precompile(source));
}
```
--------------------------------
### Ember Application Initialization and Routing
Source: https://github.com/emberjs/ember.js/wiki/Ways-to-start-a-new-app
This snippet demonstrates the basic setup for an Ember application, including creating the application instance, defining controllers, views, and templates, and setting up a router with basic routes and transitions. It's useful for understanding the core structure of an Ember app.
```javascript
App = Ember.Application.create();
App.ApplicationController = Ember.Controller.extend();
App.ApplicationView = Ember.View.extend({ templateName: 'application' });
App.HomeView = Ember.View.extend({ templateName: 'home' });
App.AboutView = Ember.View.extend({ templateName: 'about' });
App.router = Ember.Router.create({
root: Ember.Route.extend({
index: Ember.Route.extend({
route: '/',
connectOutlets: function (router) {
router.get('applicationController').connectOutlet('home');
},
}),
about: Ember.Route.extend({
route: '/about',
connectOutlets: function (router) {
router.get('applicationController').connectOutlet('about');
},
}),
showHome: Ember.Route.transitionTo('home'),
showAbout: Ember.Route.transitionTo('about')
})
});
```
--------------------------------
### UppercaseReference Example
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/05-validators.md
Demonstrates the usage of UppercaseReference and its tag for tracking value changes and validation.
```javascript
let uppercaseReference = new UppercaseReference(nameReference);
uppercaseReference.value(); // => 'GODFREY CHAN'
uppercaseReference.tag.value(); // => 1
uppercaseReference.tag.validate(1); // => true
set(person, 'name', 'Yehuda Katz');
uppercaseReference.tag.validate(1); // => false
uppercaseReference.value(); // => 'YEHUDA KATZ'
uppercaseReference.tag.value(); // => 2
```
--------------------------------
### Component Layout Template Example
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/11-glossary.md
Demonstrates a component's layout template which includes a {{yield}} to render passed content. This is the primary template of a component.
```html
{{yield}}
```
--------------------------------
### Glimmer Playground Example Template
Source: https://github.com/emberjs/ember.js/blob/main/packages/@glimmer/compiler/lib/wire-encoding.md
The source Handlebars template used in the Glimmer Playground example.
```html
Welcome to the Glimmer Playground!
You have clicked the button {{count}} times.
```
--------------------------------
### Clone and Build Ember.js
Source: https://github.com/emberjs/ember.js/blob/main/CONTRIBUTING.md
Steps to clone the Ember.js repository and build the project locally. Ensure Node.js and pnpm are installed before proceeding.
```sh
# clone the latest ember.js directory from github
- git clone https://github.com/emberjs/ember.js.git
# cd to the cloned ember.js directory
- cd ember.js
# ensure Node.js and pnpm are installed
# build ember.js
- pnpm install
- pnpm build
```
--------------------------------
### Example String Encoding
Source: https://github.com/emberjs/ember.js/blob/main/packages/@glimmer/compiler/lib/wire-encoding.md
Demonstrates how a simple string literal like '"hello world"' is encoded. It uses the character 'q' (0x34), which signifies a primitive string without escapes, followed by the string content and a closing quote.
```javascript
qhello world"
```
--------------------------------
### Format Feature Entry with RFC Link
Source: https://github.com/emberjs/ember.js/blob/main/RELEASE.md
Example of a CHANGELOG entry for a new feature, linking to the relevant RFC.
```markdown
- [#20464](https://github.com/emberjs/ember.js/pull/20464) [FEATURE] Create public import for uniqueId helper per [RFC #659](https://rfcs.emberjs.com/id/0659-unique-id-helper).
```
--------------------------------
### Initialize Ember Test Helpers and Set Testing Mode
Source: https://github.com/emberjs/ember.js/blob/main/index.html
Imports and runs the QUnit setup helper for Ember.js and explicitly sets the testing mode to true. This ensures Ember's debugging features are active during tests.
```javascript
import setupQUnit from './packages/internal-test-helpers/lib/ember-dev/setup-qunit.ts';
import { setTesting } from './packages/@ember/debug/index.ts';
setupQUnit();
setTesting(true);
```
--------------------------------
### Compile and Render a Glimmer Component
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/embedding/05-components.md
Demonstrates the compilation of a Glimmer component's template and its subsequent rendering at runtime. Includes setup for helpers and state management.
```ts
import { Component, Context } from '@glimmer/opcode-compiler';
import { artifacts } from '@glimmer/program';
import { precompile } from '@glimmer/compiler';
/// COMPILATION
let source = `
{{#let "hello" "world" as |hello world|}}
function serialize(element: SimpleElement): string {
return new Serializer(voidMap).serialize(element);
}
```
--------------------------------
### Lint Code Changes
Source: https://github.com/emberjs/ember.js/blob/main/CONTRIBUTING.md
Check your code changes against the project's style guide using prettier.
```bash
pnpm lint
```
--------------------------------
### HTTP Conditional GET Request with If-None-Match
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/05-validators.md
Shows a conditional GET request using the If-None-Match header with a cached ETag.
```http
GET /motd HTTP/1.1
If-None-Match: "0267aa812d66aafb7c4ffb790d8b5ffc"
Host: example.com
```
--------------------------------
### Run Ember Tests in Server Mode
Source: https://github.com/emberjs/ember.js/blob/main/smoke-tests/app-template/README.md
Starts a development server that runs Ember tests and re-runs them on code changes.
```bash
npm run test:ember -- --server
```
--------------------------------
### HTTP ETag Header Example
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/05-validators.md
Illustrates an HTTP response header including an ETag, used for content revalidation.
```http
HTTP/1.1 200 OK
Date: Wed, 30 Mar 2016 00:00:00 GMT
Content-Type: text/plain
ETag: "0267aa812d66aafb7c4ffb790d8b5ffc"
Content-Length: 12
Hello world!
```
--------------------------------
### Glimmer VM Opcode Examples
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/11-glossary.md
Lists common opcodes used by the Glimmer VM to compile templates into executable instructions. These opcodes represent operations like text appending, frame manipulation, and element flushing.
```text
0x16 Text - append a DOM Text node
0x30 PushFrame - push a new frame on to the stack
0x1F FlushElement - flush a newly-created element to DOM (or stream in SSR case)
0x40 CreateComponent - instantiate a component class and push it on to the stack
```
--------------------------------
### Example Usage of ConcatReference and UppercaseReference
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/05-validators.md
Demonstrates how to use ConcatReference and UppercaseReference with sample data. Shows how the computed value updates when the input data changes.
```typescript
//
let book = {
title: 'The Lord of the Rings',
subtitle: 'The Fellowship of the Ring'
};
let titleReference: Reference = {
value() {
return book.title;
}
};
let seperatorReference: Reference = {
value() {
return ': ';
}
};
let subtitleReference: Reference = {
value() {
return book.subtitle;
}
};
let result: Reference = (
new UppercaseReference(
new ConcatReference(
titleReference,
seperatorReference,
subtitleReference
)
)
);
result.value(); // => 'THE LORD OF THE RINGS: THE FELLOWSHIP OF THE RING'
book.subtitle = 'The Two Towers';
result.value(); // => 'THE LORD OF THE RINGS: THE TWO TOWERS'
```
--------------------------------
### Format Bugfix Entry with Multiple PRs
Source: https://github.com/emberjs/ember.js/blob/main/RELEASE.md
Example of a CHANGELOG entry for a bugfix that consolidates multiple related PRs.
```markdown
- [#12345](https://example.org/emberjs/ember.js/pull/12345) / [#67890](https://example.org/emberjs/ember.js/pull/67890) [BUGFIX] Fix an exception thrown only on Tuesdays.
```
--------------------------------
### Accessing Tests in Browser
Source: https://github.com/emberjs/ember.js/blob/main/CONTRIBUTING.md
Open the Ember.js test runner in your browser after starting the development server.
```bash
http://localhost:4200/tests/index.html
```
--------------------------------
### Simple Reference Example
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/04-references.md
Demonstrates creating a simple Reference that captures the current value of a JavaScript variable. Calling `value()` always returns the latest value.
```typescript
let foo = 1;
let fooReference: Reference = {
value() {
return foo;
}
};
fooReference.value(); // => 1
foo++;
fooReference.value(); // => 2
```
--------------------------------
### Render Component with External State
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/embedding/04-external-helpers.md
Demonstrates rendering a Glimmer component with initial state and updating it to trigger a rerender. Requires setup of the Glimmer runtime, program artifacts, and a compilable component.
```typescript
import { Component, Context } from '@glimmer/opcode-compiler';
import { artifacts } from '@glimmer/program';
import { precompile } from '@glimmer/compiler';
let source = `
{{#let "hello" "world" as |hello world|}}
{{hello}} {{world}}{{this.prefix}}
{{/let}}
`;
let context = Context();
let component = Compilable(source));
let handle = component.compile(context);
let program = artifacts(context);
function Compilable(source: string): CompilableProgram {
return Component(precompile(source));
}
import createHTMLDocument from '@simple-dom/document';
import { AotRuntime, renderAot } from '@glimmer/runtime';
import Serializer from '@simple-dom/serializer';
import voidMap from '@simple-dom/void-map';
import { State } from '@glimmer/references';
let document = createHTMLDocument();
let runtime = AotRuntime(document, program);
let main = document.createElement('main');
let state = State({ prefix: '!' });
let cursor = { element: main, nextSibling: null };
let iterator = renderAot(runtime, handle, cursor, state);
let result = iterator.sync();
console.log(serialize(element));
//
function serialize(element: SimpleElement): string {
return new Serializer(voidMap).serialize(element);
}
```
--------------------------------
### JavaScript Constant Pool Example
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/11-glossary.md
Shows a JavaScript representation of a string constant pool, where common strings are stored in an array. This pool is used by the VM at runtime to resolve handles.
```javascript
const STRING_CONSTANTS = ['div'];
```
--------------------------------
### Configure Ember Environment for Testing
Source: https://github.com/emberjs/ember.js/blob/main/index.html
Sets up the Ember environment for testing, including enabling optional features and configuring deprecation warnings based on URL parameters. This code should be included early in your test runner setup.
```javascript
import 'qunit/qunit/qunit.js';
import 'qunit/qunit/qunit.css';
window.EmberENV = {}; // Test under octane defaults
EmberENV._DEFAULT_ASYNC_OBSERVERS = true; // Handle testing feature flags
if (QUnit.urlParams.ENABLE_OPTIONAL_FEATURES) {
EmberENV.ENABLE_OPTIONAL_FEATURES = true;
}
EmberENV['RAISE_ON_DEPRECATION'] = QUnit.urlParams.RAISE_ON_DEPRECATION ? QUnit.urlParams.RAISE_ON_DEPRECATION === 'true' : true;
if (QUnit.urlParams.ALL_DEPRECATIONS_ENABLED) {
EmberENV['_ALL_DEPRECATIONS_ENABLED'] = true;
}
if (QUnit.urlParams.OVERRIDE_DEPRECATION_VERSION) {
EmberENV['_OVERRIDE_DEPRECATION_VERSION'] = QUnit.urlParams.OVERRIDE_DEPRECATION_VERSION;
}
QUnit.config.urlConfig.push({
id: 'OVERRIDE_DEPRECATION_VERSION',
value: ['20.0.0', '6.0.0', '5.12.0'],
label: 'Deprecation Version',
});
QUnit.config.urlConfig.push({
id: 'skip_tests_with_target_blank',
label: 'Skip tests w/ target _blank',
});
```
--------------------------------
### Mermaid Diagram of Ember Reactivity System Phases
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/reactivity/system-phases.md
Visualizes the flow between Setup, Render, Idle, and Action phases within the reactive loop of the Ember.js application.
```mermaid
---
config:
theme: base
themeVariables:
primaryColor: "#b9cccc"
secondaryColor: "#ffffff"
tertiaryColor: "#ff0000"
background: "#f9ffff"
lineColor: "#005f5f"
mainBkg: "#9fe9e9"
textColor: "#005f5f"
---
stateDiagram
direction LR
state ReactiveLoop {
direction LR
Render --> Idle
Idle --> Action
Action --> Render
Render
Idle
Action
}
[*] --> Setup:App Boot
Setup --> Render:Initial Render
ReactiveLoop --> [*]:App cleanup
ReactiveLoop:Reactive Loop
Setup:Setup state
classDef transition fill:red
```
--------------------------------
### Build Application
Source: https://github.com/emberjs/ember.js/blob/main/smoke-tests/v2-app-template/README.md
Builds the application for deployment. Use `--mode development` for development builds.
```bash
npm exec vite build --mode development
```
```bash
npm run build
```
--------------------------------
### On Modifier Example in Handlebars
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/11-glossary.md
Shows an example of an 'on' modifier used to bind DOM events, such as a click event, to an element. This modifier attaches an event listener.
```handlebars
```
--------------------------------
### Build Production Version
Source: https://github.com/emberjs/ember.js/blob/main/smoke-tests/app-template/README.md
Compiles the application for production, optimized for performance and size.
```bash
npm run build
```
--------------------------------
### Initialize Ember.js Benchmark App
Source: https://github.com/emberjs/ember.js/blob/main/smoke-tests/benchmark-app/index.html
This snippet shows the main entry point for the Ember.js benchmark application. It imports the runBenchmark function and the Application class, then calls runBenchmark and creates the application instance.
```javascript
import { runBenchmark } from './app/run-benchmark.js';
import Application from './app/app';
import environment from './app/config/environment';
runBenchmark();
Application.create(environment.APP);
```
--------------------------------
### EntityTag Interface Definition
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/05-validators.md
Defines the interface for an EntityTag, which includes methods to get a validation ticket and validate it.
```typescript
interface EntityTag {
value(): T;
validate(ticket: T): boolean;
}
```
--------------------------------
### Run Unit Tests
Source: https://github.com/emberjs/ember.js/blob/main/smoke-tests/app-template/README.md
Executes the project's unit tests.
```bash
npm run test
```
--------------------------------
### Create New Beta Branch
Source: https://github.com/emberjs/ember.js/blob/main/RELEASE.md
Creates a new local branch named 'beta' for preparing a beta release.
```bash
git co -B beta
```
--------------------------------
### List All Smoke Test Scenarios
Source: https://github.com/emberjs/ember.js/blob/main/CONTRIBUTING.md
Use this command to list all available scenarios within the smoke tests directory. Ensure you are in the correct directory before running.
```sh
cd smoke-tests/scenarios
pnpm test:list
```
--------------------------------
### HTTP 304 Not Modified Response
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/05-validators.md
Example of an HTTP 304 Not Modified response, indicating cached content is still valid.
```http
HTTP/1.1 304 Not Modified
Date: Wed, 30 Mar 2016 00:30:00 GMT
ETag: "0267aa812d66aafb7c4ffb790d8b5ffc"
Content-Length: 0
```
--------------------------------
### Initialize Runtime Environment
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/embedding/02-minimum-environment.md
Create a `RuntimeContext` using `@glimmer/runtime` by providing the document and program payload. This context is used by the Glimmer VM to execute compiled components.
```typescript
import { AotRuntime } from '@glimmer/runtime';
let runtime = AotRuntime(document, payload);
```
--------------------------------
### Use Custom Helper in Template
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/embedding/04-external-helpers.md
Incorporate the 'increment' helper into the template to dynamically update values. This example increments the 'count' property.
```diff
let source = `
{{#let "hello" "world" as |hello world|}}
-
{{/let}}
`;
```
--------------------------------
### Array Destructuring in JavaScript
Source: https://github.com/emberjs/ember.js/blob/main/STYLEGUIDE.md
Use array destructuring for decomposing simple arrays. This example splits a string into two parts based on a delimiter.
```javascript
// array destructuring
var fullName = 'component:foo-bar';
var [first, last] = fullName.split(':');
```
--------------------------------
### PrimitiveReference Implementation in Glimmer
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/04-references.md
This class represents a reference to a primitive value. Its get() method always returns NULL_REFERENCE as primitive values do not have properties.
```typescript
class PrimitiveReference implements PathReference {
private innerValue: T;
constructor(value: T) {
this.innerValue = value;
}
value(): T {
return this.innerValue;
}
get(path: string): PathReference {
return NULL_REFERENCE;
}
}
```
--------------------------------
### Generate Changelog for Beta Release
Source: https://github.com/emberjs/ember.js/blob/main/RELEASE.md
Generates a changelog for the beta release by comparing the main branch with the previous beta. The PRIOR_VERSION should be the SHA of the last common commit. Output is copied to the clipboard.
```bash
HEAD=main PRIOR_VERSION=3daedddaafd638a4a6b12e0265df30255d1512e5 ./bin/changelog.cjs | uniq | pbcopy
```
--------------------------------
### Environment Variable Replacements in Production
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/development/build-constraints.md
Shows how environment variables are replaced with static values in production builds. These replacements are performed by the Rollup replace plugin.
```javascript
// Production builds:
// import.meta.env.MODE → "production"
// import.meta.env.DEV → false
// import.meta.env.PROD → true
// import.meta.env.VM_LOCAL_DEV → false
```
--------------------------------
### UppercaseReference with RevisionTag
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/05-validators.md
An example of a versioned reference that incorporates a revision tag. It delegates tag management to the underlying data source, ensuring freshness is propagated.
```typescript
interface VersionedReference extends Reference {
tag: RevisionTag;
}
class UppercaseReference implements VersionedReference {
public tag: RevisionTag;
private str: Reference;
constructor(str: VersionedReference) {
this.tag = str.tag;
this.str = str;
}
value(): string {
return this.str.value().toUpperCase();
}
}
```
```typescript
const person: TrackedObject = {
tag: new DirtyableTag(),
name: 'Godfrey Chan'
};
let nameReference: VersionedReference = {
tag: person.tag,
value() {
return person.name;
}
};
```
--------------------------------
### Define Multiple Components and Helpers
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/embedding/05-components.md
Shows how to define multiple components and helpers, including their source code, handles, and capabilities, for use with the Glimmer runtime resolver.
```ts
// New imports:
import { MINIMAL_CAPABILITIES } from '@glimmer/opcode-compiler';
import { TEMPLATE_ONLY_COMPONENT } from '@glimmer/runtime';
// A map of helpers to runtime handles (that will be passed to the runtime resolver).
const HELPERS = {
increment: 0,
};
// A map of components to their source code and the runtime handle (that will be passed
// to the runtime resolver).
const COMPONENTS: Dict<{ source: string; handle: number }> = {
Second: {
source: `
`,
handle: 1,
},
};
// Used to make lookup by the RuntimeResolver straightforward
const TABLE = [
increment, // 0
TEMPLATE_ONLY_COMPONENT // 1
];
const RESOLVER_DELEGATE: ResolverDelegate = {
lookupComponent(name: string): Option | void {
let component = COMPONENTS[name];
if (component === null) return null;
let { handle, source } = component;
return {
handle,
compilable: Compilable(source),
capabilities: MINIMAL_CAPABILITIES,
};
},
lookupHelper(name: keyof typeof HELPERS): Option | void {
if (name in HELPERS) return HELPERS[name];
},
};
const RUNTIME_RESOLVER: RuntimeResolver = {
resolve(handle:number): ResolvedValue | void {
if (handle < TABLE.length) {
return TABLE[handle];
}
}
};
```
--------------------------------
### Pseudocode for Primitive Reactive Storage and Cache
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/reactivity/index.md
Implementation of Snapshot, PrimitiveCell, and PrimitiveCache. These primitives support law-abiding snapshots for primitive root storage and cached computations.
```typescript
interface Tag {
// A tag is a unique identifier for a piece of reactive data.
// It is used to track changes and invalidate caches.
}
interface Runtime {
// The runtime provides the context for reactive operations.
// It tracks the current frame and manages tag consumptions.
currentFrame: Frame;
consumeTag(tag: Tag): void;
}
interface Frame {
// A frame represents a single execution of a reactive computation.
// It tracks the tags that were consumed during its execution.
tags: Set;
}
class Snapshot {
constructor(public readonly tag: Tag, public readonly value: T) {}
}
class PrimitiveCell {
private _tag: Tag;
private _value: Snapshot;
constructor(initialValue: any) {
this._tag = createTag();
this._value = new Snapshot(this._tag, initialValue);
}
get value(): any {
// When the value is accessed, consume the cell's tag.
consumeTag(runtime, this._tag);
return this._value.value;
}
set value(newValue: any) {
// When the value is set, create a new tag and snapshot.
this._tag = createTag();
this._value = new Snapshot(this._tag, newValue);
}
}
class PrimitiveCache {
private _tag: Tag;
private _value: Snapshot;
private _compute: (runtime: Runtime) => T;
constructor(compute: (runtime: Runtime) => T) {
this._tag = createTag();
this._compute = compute;
this._value = new Snapshot(this._tag, compute(runtime)); // Initial computation
}
get value(): T {
// When the cached value is accessed, consume the cache's tag.
consumeTag(runtime, this._tag);
return this._value.value;
}
// Invalidate the cache and recompute the value.
// This would typically be triggered by changes in dependencies.
invalidate(): void {
this._tag = createTag();
this._value = new Snapshot(this._tag, this._compute(runtime));
}
}
// Helper functions (assuming 'runtime' and 'createTag', 'consumeTag' are defined elsewhere)
declare const runtime: Runtime;
declare function createTag(): Tag;
declare function consumeTag(runtime: Runtime, tag: Tag): void;
// Example Usage:
const cell = new PrimitiveCell(10);
const cachedValue = new PrimitiveCache(runtime => cell.value * 2);
console.log(cachedValue.value); // Accesses cell.value, consumes cell's tag, and caches result
cell.value = 20; // Updates cell, invalidating any dependent caches implicitly
// To reflect the change, the cache would need to be invalidated or recomputed.
// In a real system, this invalidation is driven by tag changes.
// For this pseudocode, we'll manually invalidate:
// cachedValue.invalidate();
// console.log(cachedValue.value); // Recomputes and returns 40
```
--------------------------------
### Push Beta Release Tag
Source: https://github.com/emberjs/ember.js/blob/main/RELEASE.md
Pushes the newly created beta release tag to the remote repository.
```bash
git push origin v5.12.0-beta.2-ember-source
```
--------------------------------
### Example Usage of PathLookupReference
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/04-references.md
Demonstrates how to use PathLookupReference to access nested properties and observe updates when the context changes. This mirrors Handlebars' dynamic segment behavior.
```typescript
let context = {
user: { name: { first: 'Godfrey', last: 'Chan' } },
motd: 'Welcome back!'
}
let contextReference: Reference = {
value() {
return context;
}
};
// {{user.name.first}}
let firstName = new PathLookupReference(contextReference, 'user.name.first');
// {{motd}}
let motd = new PathLookupReference(contextReference, 'motd');
firstName.value(); // => 'Godfrey'
motd.value(); // => 'Welcome back!'
context.user.name = { first: 'Yehuda', last: 'Katz' };
firstName.value(); // => 'Yehuda'
```
--------------------------------
### Define ResolverDelegate for Helper Lookup
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/embedding/04-external-helpers.md
Implement a ResolverDelegate to map helper names to numerical handles during compilation. This example maps the 'increment' helper to handle 0.
```typescript
const RESOLVER_DELEGATE = {
lookupHelper(name: string): Option {
if (name === 'increment') return 0;
return null;
},
};
```
--------------------------------
### Generate Stable Release Changelog
Source: https://github.com/emberjs/ember.js/blob/main/RELEASE.md
Generates the changelog for a stable release. The PRIOR_VERSION should be the last beta release of the series.
```bash
HEAD=beta PRIOR_VERSION=v5.12.0-beta.6-ember-source ./bin/changelog.cjs | uniq | pbcopy
```
--------------------------------
### Create a SimpleDOM Document
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/embedding/02-minimum-environment.md
Instantiate a document object using `@simple-dom/document`. This provides a minimal DOM implementation suitable for rendering Glimmer components in environments like Node.js.
```typescript
import createHTMLDocument from '@simple-dom/document';
let document = createHTMLDocument();
```
--------------------------------
### Runtime Handle Resolution
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/11-glossary.md
Demonstrates how the Glimmer VM resolves a handle (operand) from an instruction to its corresponding string value from the constant pool at runtime.
```javascript
let handle = instruction.operand1; // 0
let tagName = STRING_CONSTANTS[handle];
```
--------------------------------
### Build Development Version
Source: https://github.com/emberjs/ember.js/blob/main/smoke-tests/app-template/README.md
Compiles the application for development, typically with debugging enabled.
```bash
npm exec ember build
```
--------------------------------
### Implement RuntimeResolver for Handle Resolution
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/embedding/04-external-helpers.md
Create a RuntimeResolver to convert numerical handles back into their corresponding helper functions at runtime. This example resolves handle 0 to the 'increment' function.
```typescript
const RUNTIME_RESOLVER = {
resolve(handle: number) {
if (handle === 0) {
return increment;
}
},
};
function increment(args: VMArguments): Reference {
let arg = args.positional.at(0);
return map(arg, i => i + 1);
}
```
--------------------------------
### Pseudo-Implementation of createCache
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/reactivity/reactive-abstractions.md
Provides a pseudo-implementation of the createCache primitive, demonstrating dependency tracking, value coherence, and transactional consistency. It requires a runtime object with begin, commit, consume, and current methods.
```typescript
const COMPUTE = new WeakMap();
export function createCache(fn) {
const cache = {};
let last = undefined;
COMPUTE.set(cache, () => {
if (last && last.revision >= last.tag.revision) {
runtime.consume(last.tag);
return last.value;
}
runtime.begin();
try {
const result = fn();
const tag = runtime.commit();
runtime.consume(tag);
last = { value: result, tag, revision: runtime.current() };
return result;
} catch {
last = undefined;
}
});
return cache;
}
export function getCache(cache) {
const fn = COMPUTE.get(cache);
if (!fn) {
throw new Error('You must only call `getCache` with the return value of `createCache`');
}
return fn();
}
```
--------------------------------
### Expression Primitive Bit Pattern
Source: https://github.com/emberjs/ember.js/blob/main/packages/@glimmer/compiler/lib/wire-encoding.md
Illustrates the bit pattern for primitive types within an expression. It starts with a '1' flag, followed by a 3-bit tag indicating the type, and ends with type-specific representation bits.
```plaintext
1 TAG REPR
| | |
| | | the last two bits are type-specific representation
| | the tag is a three-bit representation of the primitive type
| a primitive always starts with "1"
```
--------------------------------
### Component Invocation with Content
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/11-glossary.md
Shows how to invoke a component and pass content to be rendered within its layout. The content is placed between the component's opening and closing tags.
```html
Hello World!
```
--------------------------------
### Glimmer Reference Interface Definition
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/embedding/03-adding-state.md
This TypeScript interface defines the `Reference` primitive used in Glimmer for working with external data. It includes methods for getting values and child properties, along with a `Tag` for validation.
```ts
export interface Reference {
value(): T;
get(key: string): Reference;
tag: Tag;
}
export interface Tag {
value(): number;
validate(snapshot: number): boolean;
}
```
--------------------------------
### Update State and Render with Helper
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/embedding/04-external-helpers.md
Initialize the component's state with a 'count' property and render the template. The output reflects the incremented count. Subsequent updates also show the correct incremented value.
```diff
- let state = State({ prefix: '!' });
+ let state = State({ prefix: '!', count: 5 });
let cursor = { element: main, nextSibling: null };
let iterator = renderAot(runtime, handle, cursor, state);
let result = iterator.sync();
console.log(serialize(element));
- //
```
--------------------------------
### Update package.json for Beta Release
Source: https://github.com/emberjs/ember.js/blob/main/RELEASE.md
Sets the version in package.json to the new beta version.
```bash
5.12.0-beta.2
```
--------------------------------
### Output and Run Smoke Test Scenario Interactively
Source: https://github.com/emberjs/ember.js/blob/main/CONTRIBUTING.md
Generate the full application code for a specific scenario to a specified output directory. You can then navigate to that directory and run the application interactively.
```sh
cd smoke-tests/scenarios
pnpm test:output --scenario $SCENARIO_NAME --outdir /tmp/my-scenario
cd /tmp/my-scenario
pnpm start
```
--------------------------------
### Load Test Files Dynamically with Vite
Source: https://github.com/emberjs/ember.js/blob/main/index.html
Uses Vite's `import.meta.glob` to dynamically import all test files within specified directories. The `eager: true` option ensures all tests are loaded immediately.
```javascript
let s = document.createElement('script');
s.src = '/testem.js';
document.body.append(s);
// tests in internal packages
import.meta.glob('./packages/@ember/-internals/*/tests/**/\*.{js,ts,gjs,gts}', {
eager: true,
});
// tests in scoped packages
import.meta.glob('./packages/*/\*/tests/**/\*.{js,ts,gjs,gts}', {
eager: true,
});
// tests in non-scoped packages
import.meta.glob('./packages/*/tests/**/\*.{js,ts,gjs,gts}', {
eager: true,
});
// packages originally authored in glimmer-vm repo have a different test
// naming convention
import.meta.glob(
'./packages/{@glimmer,@glimmer-workspace}/*/test/**/\*-test.{js,ts,gjs,gts}',
{
eager: true,
}
);
```
--------------------------------
### Generate Beta Release Changelog
Source: https://github.com/emberjs/ember.js/blob/main/RELEASE.md
Generates the changelog for a beta release using a custom script. Ensure to set the correct HEAD and PRIOR_VERSION.
```bash
HEAD=beta PRIOR_VERSION=v5.12.0-beta.1-ember-source ./bin/changelog.cjs | uniq | pbcopy
```
--------------------------------
### Create a Compilation Context
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/embedding/02-minimum-environment.md
Initialize a minimal compilation context using `@glimmer/opcode-compiler`. This context is essential for compiling all components within a program before execution.
```typescript
import { Context } from '@glimmer/opcode-compiler';
let context = Context();
```
--------------------------------
### Object Literal Creation
Source: https://github.com/emberjs/ember.js/blob/main/STYLEGUIDE.md
Use the literal form for creating objects. This is the standard and most concise way to initialize an object.
```javascript
var foo = {};
```
--------------------------------
### Environment Variable Replacements in Development
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/development/build-constraints.md
Details the environment variable replacements for development builds, including the injection of a DEBUG constant. Note that VM_LOCAL_DEV is true only in the Vite dev server.
```javascript
// Development builds:
// import.meta.env.MODE → "development"
// import.meta.env.DEV → DEBUG (with import { DEBUG } from '@glimmer/env' injected)
// import.meta.env.PROD → !DEBUG
// import.meta.env.VM_LOCAL_DEV → false (becomes true only in Vite dev server)
```
--------------------------------
### Link Local Ember Source
Source: https://github.com/emberjs/ember.js/blob/main/CONTRIBUTING.md
Link your local Ember source code to your application directory to test changes.
```bash
cd ../your-app-directory/
pnpm link ../../path/to/ember-source
```
--------------------------------
### Update Runtime with RuntimeResolver
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/embedding/04-external-helpers.md
Adjust the runtime initialization to pass the RuntimeResolver, allowing the system to resolve handles to helper functions.
```diff
import createHTMLDocument from '@simple-dom/document';
import { AotRuntime, renderAot } from '@glimmer/runtime';
import Serializer from '@simple-dom/serializer';
import voidMap from '@simple-dom/void-map';
import { State } from '@glimmer/references';
let document = createHTMLDocument();
- let runtime = Runtime(document, payload);
+ let runtime = Runtime(document, payload, RUNTIME_RESOLVER);
let main = document.createElement('main');
let state = State({ prefix: '!' });
let cursor = { element: main, nextSibling: null };
```
--------------------------------
### Pseudocode for Higher-Level Reactive Constructs
Source: https://github.com/emberjs/ember.js/blob/main/internal-docs/guides/reactivity/index.md
Implementations of higher-level reactive constructs using the previously defined reactive primitives. These demonstrate composition of reactive primitives.
```typescript
// Assuming PrimitiveCell, PrimitiveCache, Snapshot, Tag, Runtime, createTag, consumeTag are defined as above.
// Example: A reactive signal that can be read and written.
class Signal {
private _cell: PrimitiveCell;
constructor(initialValue: T) {
this._cell = new PrimitiveCell(initialValue);
}
get value(): T {
return this._cell.value;
}
set value(newValue: T) {
this._cell.value = newValue;
}
}
// Example: A reactive computed value based on other signals.
class Computed {
private _cache: PrimitiveCache;
constructor(computeFn: (runtime: Runtime) => T) {
this._cache = new PrimitiveCache(computeFn);
}
get value(): T {
return this._cache.value;
}
}
// Example Usage:
const count = new Signal(0);
const doubledCount = new Computed(runtime => count.value * 2);
console.log(doubledCount.value); // Accesses count.value, computes and returns 0
count.value = 5;
console.log(doubledCount.value); // Accesses count.value, recomputes and returns 10
// Helper functions (assuming 'runtime' and other primitives are defined elsewhere)
declare const runtime: Runtime;
// Note: In a real system, the invalidation of Computed values would be automatic
// when their dependencies (like 'count' signal) change, driven by the tag system.
// The PrimitiveCache's invalidate() method is a simplified representation of this.
```
--------------------------------
### Push Release Tag
Source: https://github.com/emberjs/ember.js/blob/main/RELEASE.md
Pushes the newly created release tag to the remote origin.
```bash
git push origin v5.12.0-beta.1-ember-source
```
--------------------------------
### Force Push Beta Branch
Source: https://github.com/emberjs/ember.js/blob/main/RELEASE.md
Force pushes the 'beta' branch to the remote origin, overwriting remote history.
```bash
git push -f origin beta
```
--------------------------------
### Tag Beta Release Commit
Source: https://github.com/emberjs/ember.js/blob/main/RELEASE.md
Tags the current commit with the beta release version.
```bash
git tag v5.12.0-beta.2-ember-source
```
--------------------------------
### Ember.js Application Bootstrapping
Source: https://github.com/emberjs/ember.js/blob/main/smoke-tests/v2-app-template/index.html
Shows the core JavaScript code for initializing an Ember.js application. It imports the main Application class and environment configuration, then creates an instance of the application.
```javascript
import Application from './app/app';
import environment from './app/config/environment';
Application.create(environment.APP);
```
--------------------------------
### Create a Glimmer Component
Source: https://github.com/emberjs/ember.js/blob/main/packages/@glimmer/component/README.md
Import the Component class and extend it to create a new Glimmer component. Define getters for computed properties and use the tag for the component's template.
```glimmer-ts
import Component from '@glimmer/component';
export default class MyComponent extends Component {
get doubled() {
return this.args.foo * 2;
}
{{@foo}} * 2 === {{this.doubled}}
}
```