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
35 changes: 33 additions & 2 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
cache: pnpm
- name: Install Dependencies
run: pnpm install --frozen-lockfile
- run: pnpm build

- name: Lint Addon
run: pnpm lint
Expand Down Expand Up @@ -82,11 +83,11 @@ jobs:
run: pnpm test:ember --launch ${{ matrix.browser }}
working-directory: test-app

try-scenarios:
test_pre_built_ins:
name: ${{ matrix.try-scenario }}
runs-on: ubuntu-latest
needs: "test"
timeout-minutes: 10
needs: "lint"

strategy:
fail-fast: false
Expand All @@ -98,6 +99,36 @@ jobs:
- ember-lts-5.4
- ember-lts-5.8
- ember-lts-5.12
- ember-lts-6.4

steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- name: Install Dependencies
run: pnpm install --frozen-lockfile

- name: Run Tests
working-directory: test-app
run: >-
node_modules/.bin/ember try:one ${{ matrix.try-scenario }}
--skip-cleanup

try-scenarios:
name: ${{ matrix.try-scenario }}
runs-on: ubuntu-latest
needs: "test"
timeout-minutes: 10

strategy:
fail-fast: false
matrix:
try-scenario:
- native-collections-support
- ember-lts-6.8
- ember-release
- ember-beta
- ember-canary
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# compiled output
dist/
.log/

# dependencies
node_modules/
Expand All @@ -14,3 +15,4 @@ node_modules/
npm-debug.log*
yarn-error.log
.DS_Store
tmp/
6 changes: 6 additions & 0 deletions addon/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -112,5 +112,11 @@ module.exports = {
'plugin:prettier/recommended',
],
},
{
files: ['src/-private/*', 'src/-private/new/*'],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
},
},
],
};
1 change: 0 additions & 1 deletion addon/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

# compiled output
dist/
declarations/

# npm/pnpm/yarn pack output
*.tgz
Expand Down
20 changes: 20 additions & 0 deletions addon/declarations/-private/array.d.ts
Copy link
Copy Markdown
Collaborator Author

@NullVoxPopuli NullVoxPopuli Dec 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it isn't possible to build and use those built types from source.

and it's not worth any more of my time to continue trying to coerce TS into something it's not designed to do.

(already spent too much on this already haha)

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
declare class TrackedArray<T = unknown> {
#private;
/**
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
*/
static from<T>(iterable: Iterable<T> | ArrayLike<T>): TrackedArray<T>;
/**
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
static from<T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: unknown): TrackedArray<U>;
static of<T>(...arr: T[]): TrackedArray<T>;
constructor(arr?: T[]);
}
interface TrackedArray<T = unknown> extends Array<T> {
}
export default TrackedArray;
10 changes: 10 additions & 0 deletions addon/declarations/-private/decorator.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { TrackedMap, TrackedWeakMap } from './map.ts';
import { TrackedSet, TrackedWeakSet } from './set.ts';
import TrackedArray from './array.ts';
export default function tracked<T>(obj: T[] | typeof Array): TrackedArray<T>;
export default function tracked<T>(obj: Set<T> | typeof Set): TrackedSet<T>;
export default function tracked<T, U>(obj: Map<T, U> | typeof Map): TrackedMap<T, U>;
export default function tracked<T extends object>(obj: WeakSet<T> | typeof WeakSet): TrackedWeakSet<T>;
export default function tracked<T extends object, U>(obj: WeakMap<T, U> | typeof WeakMap): TrackedWeakMap<T, U>;
export default function tracked<T extends object>(obj: T | typeof Object): T;
export default function tracked(obj: object, key: string | symbol, desc?: PropertyDescriptor): void;
36 changes: 36 additions & 0 deletions addon/declarations/-private/map.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export declare class TrackedMap<K = unknown, V = unknown> implements Map<K, V> {
private collection;
private storages;
private vals;
private readStorageFor;
private dirtyStorageFor;
constructor();
constructor(entries: readonly (readonly [K, V])[] | null);
constructor(iterable: Iterable<readonly [K, V]>);
get(key: K): V | undefined;
has(key: K): boolean;
entries(): MapIterator<[K, V]>;
keys(): MapIterator<K>;
values(): MapIterator<V>;
forEach(fn: (value: V, key: K, map: Map<K, V>) => void): void;
get size(): number;
[Symbol.iterator](): MapIterator<[K, V]>;
get [Symbol.toStringTag](): string;
set(key: K, value: V): this;
delete(key: K): boolean;
clear(): void;
}
export declare class TrackedWeakMap<K extends object = object, V = unknown> implements WeakMap<K, V> {
private storages;
private vals;
private readStorageFor;
private dirtyStorageFor;
constructor();
constructor(iterable: Iterable<readonly [K, V]>);
constructor(entries: readonly [K, V][] | null);
get(key: K): V | undefined;
has(key: K): boolean;
set(key: K, value: V): this;
delete(key: K): boolean;
get [Symbol.toStringTag](): string;
}
8 changes: 8 additions & 0 deletions addon/declarations/-private/object.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface TrackedObject {
fromEntries<T = unknown>(entries: Iterable<readonly [PropertyKey, T]>): {
[k: string]: T;
};
new <T extends Record<PropertyKey, unknown>>(...args: Record<PropertyKey, never> extends T ? [] | [T] : [T]): T;
}
export declare const TrackedObject: TrackedObject;
export default TrackedObject;
39 changes: 39 additions & 0 deletions addon/declarations/-private/set.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
export declare class TrackedSet<T = unknown> implements Set<T> {
private collection;
private storages;
private vals;
private storageFor;
private dirtyStorageFor;
constructor();
constructor(values: readonly T[] | null);
constructor(iterable: Iterable<T>);
has(value: T): boolean;
entries(): SetIterator<[T, T]>;
keys(): SetIterator<T>;
values(): SetIterator<T>;
union<U>(other: ReadonlySetLike<U>): Set<T | U>;
intersection<U>(other: ReadonlySetLike<U>): Set<T & U>;
difference<U>(other: ReadonlySetLike<U>): Set<T>;
symmetricDifference<U>(other: ReadonlySetLike<U>): Set<T | U>;
isSubsetOf(other: ReadonlySetLike<unknown>): boolean;
isSupersetOf(other: ReadonlySetLike<unknown>): boolean;
isDisjointFrom(other: ReadonlySetLike<unknown>): boolean;
forEach(fn: (value1: T, value2: T, set: Set<T>) => void): void;
get size(): number;
[Symbol.iterator](): SetIterator<T>;
get [Symbol.toStringTag](): string;
add(value: T): this;
delete(value: T): boolean;
clear(): void;
}
export declare class TrackedWeakSet<T extends object = object> implements WeakSet<T> {
private storages;
private vals;
private storageFor;
private dirtyStorageFor;
constructor(values?: readonly T[] | null);
has(value: T): boolean;
add(value: T): this;
delete(value: T): boolean;
get [Symbol.toStringTag](): string;
}
5 changes: 5 additions & 0 deletions addon/declarations/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export { default as tracked } from './-private/decorator.ts';
export { default as TrackedArray } from './-private/array.ts';
export { default as TrackedObject } from './-private/object.ts';
export { TrackedMap, TrackedWeakMap } from './-private/map.ts';
export { TrackedSet, TrackedWeakSet } from './-private/set.ts';
9 changes: 4 additions & 5 deletions addon/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,22 @@
"dist"
],
"scripts": {
"build": "concurrently 'npm:build:*'",
"build:js": "rollup --config",
"build:types": "glint --declaration",
"build": "rollup --config",
"lint": "concurrently \"npm:lint:*(!fix)\" --names \"lint:\"",
"lint:fix": "concurrently \"npm:lint:*:fix\" --names \"fix:\"",
"lint:hbs": "ember-template-lint . --no-error-on-unmatched-pattern",
"lint:hbs:fix": "ember-template-lint . --fix --no-error-on-unmatched-pattern",
"lint:js": "eslint . --cache",
"lint:js:fix": "eslint . --fix",
"lint:types": "glint",
"lint:types": "tsc --noEmit",
"prepack": "concurrently 'npm:build:*'",
"start": "concurrently 'npm:start:*'",
"start:js": "rollup --config --watch --no-watch.clearScreen",
"start:types": "glint --declaration --watch",
"test": "echo 'A v2 addon does not have tests, run tests in test-app'"
},
"dependencies": {
"@embroider/addon-shim": "^1.8.7",
"@embroider/addon-shim": "^1.10.2",
"decorator-transforms": "^2.0.0",
"ember-tracked-storage-polyfill": "^1.0.0"
},
Expand All @@ -62,6 +60,7 @@
"@babel/plugin-transform-typescript": "^7.24.4",
"@babel/runtime": "^7.26.10",
"@embroider/addon-dev": "^4.3.1",
"@embroider/macros": "^1.19.5",
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

devDep needed for types

"@glint/core": "^1.4.0",
"@glint/environment-ember-loose": "^1.4.0",
"@glint/environment-ember-template-imports": "^1.4.0",
Expand Down
47 changes: 4 additions & 43 deletions addon/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,60 +8,21 @@ const addon = new Addon({
});

export default {
// This provides defaults that work well alongside `publicEntrypoints` below.
// You can augment this if you need to.
output: addon.output(),

plugins: [
// These are the modules that users should be able to import from your
// addon. Anything not listed here may get optimized away.
// By default all your JavaScript modules (**/*.js) will be importable.
// But you are encouraged to tweak this to only cover the modules that make
// up your addon's public API. Also make sure your package.json#exports
// is aligned to the config here.
// See https://github.com/embroider-build/embroider/blob/main/docs/v2-faq.md#how-can-i-define-the-public-exports-of-my-addon
addon.publicEntrypoints(['**/*.js', 'index.js', 'template-registry.js']),

// These are the modules that should get reexported into the traditional
// "app" tree. Things in here should also be in publicEntrypoints above, but
// not everything in publicEntrypoints necessarily needs to go here.
addon.appReexports([
'components/**/*.js',
'helpers/**/*.js',
'modifiers/**/*.js',
'services/**/*.js',
]),

// Follow the V2 Addon rules about dependencies. Your code can import from
// `dependencies` and `peerDependencies` as well as standard Ember-provided
// package names.
/**
* NOTE: we have to output every module individually so that we can conditionally import some of them
*/
addon.publicEntrypoints(['index.js', '**/*.js']),
addon.dependencies(),

// This babel config should *not* apply presets or compile away ES modules.
// It exists only to provide development niceties for you, like automatic
// template colocation.
//
// By default, this will load the actual babel config from the file
// babel.config.json.
babel({
extensions: ['.js', '.gjs', '.ts', '.gts'],
babelHelpers: 'bundled',
}),

// Ensure that standalone .hbs files are properly integrated as Javascript.
addon.hbs(),

// Ensure that .gjs files are properly integrated as Javascript
addon.gjs(),

// addons are allowed to contain imports of .css files, which we want rollup
// to leave alone and keep in the published output.
addon.keepAssets(['**/*.css']),

// Remove leftover build artifacts when starting a new build.
addon.clean(),

// Copy Readme and License into published package
copy({
targets: [
{ src: '../README.md', dest: '.' },
Expand Down
Loading
Loading