tracked-tools / tracked-built-ins Goto Github PK
View Code? Open in Web Editor NEWTracked versions of JavaScript's built-in classes
License: MIT License
Tracked versions of JavaScript's built-in classes
License: MIT License
Is there anything that can be done to improve the performance of .splice
this.data = tracked([/* 10000 items */]);
console.time('splice');
this.data.splice(0, 1);
console.timeEnd('splice');
// 10ms
vs.
this.data = [/* 10000 items */];
console.time('splice');
this.data.splice(0, 1);
console.timeEnd('splice');
// 0.002
So, today I had this case:
import { tracked } from 'tracked-built-ins';
class Queue {
@tracked files = [];
update() {
this.files.push('...');
}
}
vs
import { TrackedArray } from 'tracked-built-ins';
class Queue {
files = new TrackedArray([]);
update() {
this.files.push('...');
}
}
and an #each
in the template to it:
In both cases I'd expect the {{#each}}
part to be updated once update()
is called. However, the first case did nothing, the latter one worked.
Looking into the code, the decorator usage does a passthrough to glimmer's tracked:
tracked-built-ins/addon/-private/decorator.ts
Lines 42 to 44 in 57a813c
My expectation is, that whenever @tracked
from tracked-built-ins
is able to recognize one of the supported values, than this is used. If not a fallback to glimmers @tracked
is used.
Is my assumption correct?
Note: we can't actually start on this yet because Framework still needs to figure out what the semantics should be for it!
The simplest idea, “match the built-in constructors exactly” can have some weird effects:
let original = { foo: true };
let viaObject = new Object(original);
let viaTrackedObject = new TrackedObject(original);
original.foo = false;
console.log(viaObject.foo); // `false`
console.log(viaTrackedObject); // ???
viaTrackedObject.foo = true;
console.log(original.foo); // ???
console.log(viaObject.foo); // ???
original.foo
, at least with the existing Proxy
-based implementation, so if we return the (proxied) original we end up with cases where the object is sometimes mutated in a non-tracked fashion and sometimes mutated in a tracked fashionAdditionally, we cannot ever make new TrackedObject()
return the desired type from a TypeScript point-of-view.
Related: #73.
I know that in the README it's explicitly written that they copy their arguments for safety (which is great and makes sense) but sometimes one might want to save on memory and performance when they know that the original won't be accessed any more from anywhere else. I'm fine with calling the methods UNSAFE_CREATE or something but just the ability to do that would be nice.
I actually have copy-pasted locally the implementations from this library and added that single static method.
I could open a PR if that's acceptable.
I've just installed tracked-built-ins
and got this error when doing ember s
:
Build Error (OneShot)
-private/object.js: /Users/{PATH_EDITED}/my-project/-private/object.js: Class private methods are not enabled.
65 |
66 | // @Private
67 | #readStorageFor(key) {
| ^
68 | let storage = this.#storages.get(key);
69 |
70 | if (storage === undefined) {
in /var/folders/yn/ggs6qq9d0wj8q8pz_5kr94zm0000gn/T/broccoli-95128lZBubem9LmmO/out-02-funnel
at broccoli-persistent-filter:Babel > [Babel: tracked-built-ins] (Babel: tracked-built-ins)
This is my setup:
$ ember -v
ember-cli: 3.28.3
node: 14.17.0
os: darwin x64
I also use embroider
with, I believe, latest possible versions:
"@embroider/compat": "^0.47.1",
"@embroider/core": "^0.47.1",
"@embroider/webpack": "^0.47.1",
Any help? What should I do to make it working? 🙏
Originally commented here: embroider-build/embroider#817 (comment)
While trying to get Ember 3.27 to work with my app: NullVoxPopuli/limber#117
I am using Embroider
Uncaught Error: Could not find module `@ember/-internals/utils` imported from `(require)`
missingModule loader.js:247
findModule loader.js:258
requireModule loader.js:24
<anonymous> object.js:16
js chunk.bd06e5b59763daf483e5.js:5928
__webpack_require__ chunk.909881dca69b23cf60bd.js:31
<anonymous> decorator.js:9
js chunk.bd06e5b59763daf483e5.js:5917
__webpack_require__ chunk.909881dca69b23cf60bd.js:31
<anonymous> index.js:11
js chunk.bd06e5b59763daf483e5.js:5939
__webpack_require__ chunk.909881dca69b23cf60bd.js:31
<anonymous> Ember
js chunk.bd06e5b59763daf483e5.js:5862
__webpack_require__ chunk.909881dca69b23cf60bd.js:31
<anonymous> Ember
js chunk.bd06e5b59763daf483e5.js:5873
__webpack_require__ chunk.909881dca69b23cf60bd.js:31
<anonymous> Ember
js chunk.bd06e5b59763daf483e5.js:5895
__webpack_require__ chunk.909881dca69b23cf60bd.js:31
<anonymous> Ember
js chunk.79c93d843abd4d8f4997.js:619
__webpack_require__ chunk.909881dca69b23cf60bd.js:31
<anonymous> limber.js:25
case - extenally controlled state object.
like:
var state = {
name: 'Age',
items: [ { name: 'Pet' }, { name : 'Book' } , { name: { firstName: 'foo' } } ]
}
recursive tracking example - https://gist.github.com/lifeart/d6237e0129e603b23d1aa8e8d4b07504
like makeTracked(state);
also, it's possible to add one more object tracking option - track only defined properties (without proxy), patching native getters/setters.
All tests currently fail with this error:
not ok 1 Chrome 90.0 - [undefined ms] - Global error: Uncaught TypeError: Cannot read property 'Object' of undefined at http://localhost:7357/assets/vendor.js, line 70044
---
browser log: |
{"type":"warn","text":"DEPRECATION: Usage of the Ember Global is deprecated. You should import the Ember module or the specific API instead. [deprecation id: ember-global] See https://deprecations.emberjs.com/v3.x/#toc_ember-global for more details.\n at logDeprecationStackTrace (http://localhost:7357/assets/vendor.js:36357:21)\n at HANDLERS.<computed> (http://localhost:7357/assets/vendor.js:36490:9)\n at raiseOnDeprecation (http://localhost:7357/assets/vendor.js:36384:9)\n at HANDLERS.<computed> (http://localhost:7357/assets/vendor.js:36490:9)\n at invoke (http://localhost:7357/assets/vendor.js:36502:9)\n at deprecate (http://localhost:7357/assets/vendor.js:36458:28)\n at get (http://localhost:7357/assets/vendor.js:466:53)\n at Module.callback (http://localhost:7357/assets/vendor.js:70044:20)\n at Module.exports (http://localhost:7357/assets/vendor.js:118:32)"}
{"type":"error","text":"Uncaught TypeError: Cannot read property 'Object' of undefined at http://localhost:7357/assets/vendor.js, line 70044\n","testContext":{}}
...
Resolve this so that tracked-built-ins
works with 3.27 and 3.28.
last release was April?
how can I help get the all the work since then published?
Does it make sense to introduce a TrackedArray here: more than an Array, less than an EmberArray?
The typings for the tracked
decorator in the npm package are missing an optional specifier:
export default function tracked(obj: object, key: string | symbol, desc: PropertyDescriptor): void;
should be:
export default function tracked(obj: object, key: string | symbol, desc?: PropertyDescriptor): void;
As seen on this CI run, we are failing against Ember 4 beta because of an issue with ember-template-compiler
. (Cf. tracked-tools/tracked-maps-and-sets#121 which is the same issue.)
When we make a breaking change release (relatively soon but not immediately), we should cut the TS versions which predate the current Ember LTS versions we aim to support.
Although this does not have anything to do with auto-tracking per se, for TrackedArray
to be a complete substitute for Array
, it should be possible to simply replace Array.from
with TrackedArray.from
and have the expected behavior—rather than needing to do new TrackedArray(Array.from(someIterable))
.
In line with the proposal at emberjs/rfcs#730:
strict: true
and noPropertyAccessFromIndexSignature: true
in tsconfig.json
– #315Reading array.length then calling array.push() yields an error about updating a value after using it in a computation.
Minimal repro:
import Component from '@glimmer/component';
import { tracked } from 'tracked-built-ins';
export default class MyComponent extends Component {
myArray = tracked([]);
constructor() {
super(...arguments);
this.myArray.push(this.myArray.length);
}
}
Error when component tries to load:
Uncaught Error: Assertion Failed: You attempted to update `_value` on `TrackedStorageImpl`, but it had already been used previously in the same computation. Attempting to update a value after using it in a computation can cause logical errors, infinite revalidation bugs, and performance issues, and is not supported.
[email protected]
[email protected]
This may have some relation to #29
While it made sense to ignore this previously, if we want these types to be drop-in replacements for the built-ins, we do need to support even the janky APIs.
Hi,
Is it expected to be able to write new TrackedArray<string>()
in TypeScript?
I'm seeing the following:
// This works fine. The type of foo is string[].
const foo = TrackedArray.of<string>()
foo.push("item")
// This gives the error: "Property 'push' does not exist on type 'TrackedArray<string>'. ts(2339)".
// The type of bar is `TrackedArray<string>`
const bar = new TrackedArray<string>()
bar.push("item")
Should TrackedArray<T>
be extending Array<T>
in the type definitions?
Thanks.
A tracked array's type from a consumer app only has these properties: https://github.com/pzuraq/tracked-built-ins/blob/master/addon/-private/array.ts#L110-L121
but we can use all of these: https://github.com/pzuraq/tracked-built-ins/blob/master/addon/-private/array.ts#L9-L32
but typescript is not aware of them, cause Proxies and TS are.. not great 🙃
Since Object.setPrototypeOf(TrackedArray.prototype, Array.prototype);
is a thing, I wonder if the TrackedArray class should extend from Array? idk
The types for TrackedArray don't include the newer (but fully supported) method findLast()
I think that means we just need to add it here, but not sure?
It may be worth doing a general review of all the built-ins to see what other methods have achieved full browser support since the initial implementation and ensuring those methods are properly accounted for since the built-ins are intended to have 1:1 functionality with their native counterparts.
From what I can tell, it doesn't appear that I can simply npm install
this package and use it in a non-ember project like a typical npm package. Autotracking is exactly what I need for my project, but if my assumption is correct that I can't use this (as-is) outside of ember, it looks like I may have to just grab the relevant bits (including @glimmer/tracking) and maintain a similar functionality myself.
Per my comments on tracked-tools/tracked-maps-and-sets#223 and #274, we should integrate tracked-maps-and-sets directly into this. That will simplify maintenance substantially, and it's also necessary for #316.
We are running into the Ember Global deprecation using tracked-built-ins.
#98 resolves this issue in this package, but is not yet released.
tracked-tools/tracked-maps-and-sets#80 needs to be resolved as well.
I saw this error after upgrading tracked-built-ins to v2.0.0:
Build Error (broccoli-persistent-filter:Babel > [Babel: tracked-built-ins]) in -private/object.js
/Users/nightire/Code/github.com/choice-form/mono-apps/packages/os-portal/-private/object.js: Class private methods are not enabled.
65 |
66 | // @private
> 67 | #readStorageFor(key) {
| ^
68 | let storage = this.#storages.get(key);
69 |
70 | if (storage === undefined) {
It happens with both the latest version of classic ember-cli and embroider, I've already tried with @babel/plugin-proposal-private-methods plugin, but the same error remains.
Clicking the button sets a tracked object's property to something and clicking it a second time does a delete
. That should hide some text that is shown and should log undefined
. Neither happens. I think this is a bug.
Either:
or:
@tsconfig/ember
if tsconfig/bases#102 lands soon enoughcurrently, this fails with a type error:
type XIndex = 0 | 1;
type YIndex = 0 | 1 | 2;
let arr: [XIndex, YIndex] = new TrackedArray([0, 0]])
TrrackedArray infers generic <number>
, but that's kinda incorrect here.
I can cast with as
, but obvs inference is always nice when it works, so I wan wondering if there was a way to change the definition of TrackedArray so that inference could work in this situation.
The push
method dirties the collection tag, and subsequently does a get
on the length
property (since the push()
method normally returns the length), which consumes the collection tag. This means that push()
can't be called more than once without triggering this error:
Error: You attempted to update '(an unknown tag)', but it had already been used previously in the same computation. Attempting to update a value after using it in a computation can cause logical errors, infinite revalidation bugs, and performance issues, and is not supported.
Or, more generally, the tracked array can't be further modified after push()
is called the first time.
I'm new to this project so please let me know if this is a usage error on my end, saw it during the presentation at emberconf / in the emberjs subreddit and wanted to give it a shot.
I've created a TrackedObject
on one of my components as follows:
entriesToDelete = tracked({});
I have a getter function that returns the number of entries in the TrackedObject
:
get numEntriesToDelete() {
return Object.keys(this.entriesToDelete).length;
}
I'm seeing the getter work properly when used within the same class, for instance i have some conditional logic where I show a popup dialog:
@action
showDeleteDialog() {
if (this.numEntriesToDelete > 0) {
this.isDeleteDialogVisible = true;
}
else {
this.toast.warning("No entries selected for deletion", "Warning", {});
}
}
But the problem comes when I try to pass the result of the getter as an argument to another component:
The result is @numEntries
in the other component is always returning 0 whereas the console.log
within the original component always has the correct value. If I revert back to using a regular object with re-assignments whenever a value changes in the object my logic works as expected.
Found this while trying to repro this: embroider-build/embroider#817
Reproduction: https://github.com/NullVoxPopuli/embroider-resolution-reproduction-issue-817
just yarn && yarn start
, and you get the error:
Uncaught TypeError: setting getter-only property "setupMandatorySetter"
<anonymous> object.js:20
js chunk.9323c6c3d59b6ab7919f.js:3480
__webpack_require__ chunk.2145a4d29ef12f2bf0a4.js:31
<anonymous> decorator.js:9
js chunk.9323c6c3d59b6ab7919f.js:3469
__webpack_require__ chunk.2145a4d29ef12f2bf0a4.js:31
<anonymous> index.js:11
js chunk.9323c6c3d59b6ab7919f.js:3491
__webpack_require__ chunk.2145a4d29ef12f2bf0a4.js:31
<anonymous> application.js:7
js chunk.a8d3a7bd10ad06479926.js:94
__webpack_require__ chunk.2145a4d29ef12f2bf0a4.js:31
<anonymous> embroider-resolution-reproduction-issue-817.js:91
exports loader.js:106
requireModule loader.js:27
Ember 47
<anonymous> embroider-resolution-reproduction-issue-817.js:1048
js chunk.a8d3a7bd10ad06479926.js:50
__webpack_require__ chunk.2145a4d29ef12f2bf0a4.js:31
__webpack_exports__ chunk.2145a4d29ef12f2bf0a4.js:186
O chunk.2145a4d29ef12f2bf0a4.js:68
<anonymous> chunk.2145a4d29ef12f2bf0a4.js:187
<anonymous> chunk.2145a4d29ef12f2bf0a4.js:189
chunk.9323c6c3d59b6ab7919f.js line 3480 > eval:20:3
Currently, the build reports this for TS v5.0.0 builds:
> [email protected] prepublishOnly /Users/ckrycho/dev/tracked-tools/tracked-built-ins/addon
> rollup --config
→ dist...
(!) Unresolved dependencies
https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
@babel/runtime/helpers/esm/classPrivateFieldGet (imported by src/-private/object.js, src/-private/array.ts)
(!) Generated an empty chunk
object.d
[!] (plugin Typescript) TS2792: Cannot find module 'ember-tracked-storage-polyfill'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
src/-private/map.ts (6:8)
6 } from 'ember-tracked-storage-polyfill';
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ELIFECYCLE Command failed with exit code 1.
I have yet to do any investigation, so it's possible this is a bug in any of the following places:
ember-tracked-storage-polyfill
ember-tracked-storage-polyfill
in this packagerollup-plugin-ts
I have a TrackedSet and some actions to add and remove elements. The #each
template helper shows the initial contents of the TrackedSet, but does not seem to reflect any changes. Oddly enough, #each-in
works great (the "key" is the index).
It's not clear to me whether or not this is something that is supposed to work, but it'd be cooler if it did. Ember 3.15.0, tracked-built-ins 0.2.0.
As far as I can tell Travis for Open Source is basically dead (I haven't seen a run complete in months now). Switching to GH Actions should be straightforward; we can just integrate the config used in a variety of other Ember addons for it.
I suspect this isn't actually a bug, but any help that could be given to help me track this down would be greatly appreciated!
Every keystroke in the text field causes the loop to rerender and the focus from the textfield to be lost. Check the log
- it logs on every keystroke (meaning that the loop redraws).
Adding a key="@index"
to the each
fixes the problem but that's a "hack" I guess.
The problem is this line. However, removing it will probably cause other issues. So a clever solution should be thought of.
As this addon provides only run-time functionality hence it's the great candidate for v2 addon conversion.
This would require major release.
@chriskrycho any thoughts, concerns?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.