-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add BigInt bundle #167
base: main
Are you sure you want to change the base?
Add BigInt bundle #167
Conversation
@@ -1,12 +1,12 @@ | |||
{ | |||
"name": "@js-temporal/polyfill", | |||
"version": "0.3.0", | |||
"version": "0.4.1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know the exact reason why this was v0.3.0
. But I guess it better to match package.json
's version.
I just noticed that I should deal with the following issue. (Currently, this PR works with JS but TS. ) |
#167 (comment) fixed. |
Thanks for this PR! I haven't cloned this to experiment with it, but this looks about right. That being said, I'd prefer to fix #164 first, as anyone trying to use this version along other library code that makes use of the non-bigint version will likely end up with broken code. |
Ah, I get it. So transitive deps can be a potential dual package hazard risk. At first I simply thought it would be fine as long as users don't import both bigint and non-bigint build at the same time. But it's true that two of them may be mixed at the same time as transitive deps if other library code depend on a diffrent temporal-polyfill build. Thanks for your comment! I’ll do some research. |
I could be wrong, but after a little research, it looks like you can use both bigint and jsbi version at the same time. Here's my thought: Also, since there's no code like bigint and JSBIAccording to List of bigint interfaces that are exposed as a method's or constructor's parameter:
About these parameters, The type definition only accepts List of bigint interfaces that are exposed as a get only accessor property:
About these properties, it may use JSBI in their object's internal slot, but when it is called via getter by the user, it must goes through So the mixed up code like this will work: import { Temporal } from "@js-temporal/polyfill/bigint";
import { Temporal as JSBITemporal } from "@js-temporal/polyfill";
const a = new Temporal.Instant(JSBITemporal.Now.instant().epochNanoseconds)
const b = new JSBITemporal.Instant(Temporal.Now.instant().epochNanoseconds) I'm sorry if I missed or misunderstood something. Cheers. |
I think that dual-package hazards are still likely because of the way that slots are used and implemented for branding - see #164 (comment). They aren't instanceof checks, but they do heavily rely on module-local state which would be duplicated if there were dual packages. Let's keep the discussion of the general dual-package hazards over there, but the discussion of JSBI/bigint compatibility is good to have here. Great points r.e. mixing native BigInt and JSBI - I think you are right r.e. mixing them. In particular, we do need to be very careful accepting native My understanding is that package aliases can be used to allow two versions of a project to be imported at the same time into a project - would this work to setup a set of tests we can use to exercise both versions at the same time and verify compatibility between the two versions? |
Ok!
Do you mean aliases like this? If so, Yes. I think It should do the job.
Or If you are talking about the bigint and jsbi versions in this branch, we may simply use the package self-referencing to import two different builds. // In the test file:
import { Temporal } from "@js-temporal/polyfill/bigint";
import { Temporal as JSBITemporal } from "@js-temporal/polyfill"; Note: If we want to use self-referencing in TS file, then we need TS 4.7 or higher. |
That self-referencing thing seems useful, and it's on my to-do list to bump this up to TS4.7 anyways. Last I checked a couple weeks ago, some of our build tools weren't yet compatible. Maybe we can get away with a single extensive test suite that uses the self-referencing imports between these two versions, as those should fully exercise differences between JSBI and native BigInt compat as well as other dual-package hazards. |
A single extensive test suite sounds good! But not sure what to test actually. Also, I just noticed there's a loader hook |
I was trying to write a test suite and just found that the error occurs when using methods like sample code (click to open)it('since', () => {
const { PlainDate } = Temporal;
const { PlainDate: PlainDateBigInt } = TemporalBigInt;
const a = PlainDate.from('2022-01-01');
const b = PlainDateBigInt.from('2022-01-01');
const res = b.since(a); // TypeError: invalid result at CalendarDateFromFields
equal(res, "PT0S");
}); Also, Here's what I'm trying so far. (Does it match what you imagined?) |
Well, const a = Temporal.Now.zonedDateTime('iso8601')
const b = TemporalBigInt.ZonedDateTime.from(a); // TypeError: invalid result at CalendarDateFromFields So dual package hazard can happen quite easily actually. Now I feel that it might be better to release the bigint build as a completely different package rather than a subpath export until we find some way around the dual package hazard. (Although, even if bigint release is separated, dual package hazard can still occur if CommonJS and ESM are mixed like this.) |
My concern about releasing multiple packages is that they would likely be compatible according to TypeScript, and so you could easily end up with code that compiles that doesn't work at all at runtime. This only applies if packages use Temporal types as part of their public API surface I suppose, but I'd rather not release something that has this sort of a footgun. That being said, I've had some thoughts on how to resolve these hazards, and I'll put my thoughts into a comment over in the package hazard issue shortly. |
I agree. That makes sense. |
Would it be possible to publish two separate npm packages, one that includes JSBI and one that doesn't? Does that help the dual-package problem? |
Seconding this. For those cases where existing code must continue to work using the JSBI version: instruct users to use NPM aliases and install {
// ...
"dependencies": {
// ...
"@js-temporal/polyfill" : "npm:@js-temporal/polyfill-jsbi@x.y.z"
},
"overrides": {
// ...
"@js-temporal/polyfill" : "$@js-temporal/polyfill"
}
} Yes; this would require pinning to a version. But you're already well into exceptional-case territory at that point anyway. |
I agree that
We could ship two packages, but:
R.e. aliases - that is a very interesting idea.... is there a way to make aliases apply to an entire transitive closure (tc) of dependencies? If so, then publishing two separate packages might be a solution for users who need to force the use of JSBI throughout their application (e.g. by forcing any libraries in their tc that were using the bigint package to instead use the jsbi package). I suppose that principle doesn't scale to the libraries themselves (they might directly create/manipulate bigints, so even if we swap out Temporal that code would still not work at runtime) so maybe it is a moot point? |
It might be possible to use NPM overrides in this manner: https://docs.npmjs.com/cli/v9/configuring-npm/package-json?v=true#overrides Something like (hypothetical): {
"dependencies": {
"@js-temporal/polyfill-no-bigint",
},
"overrides": {
"@js-temporal/polyfill": "$js-temporal/polyfill-no-bigint",
}
} if I understand the docs properly. |
According to caniuse.com, only Internet Explorer and Opera Mini don't support JSBI: https://caniuse.com/bigint Microsoft themselves has now disowned IE, so why does this lib need to cater to it? Going a step further, once Temporal becomes stage 4 or better, the only browsers that are going to be able to use Temporal natively already support BigInt. |
When I joined this project, there were certain interested parties (my employer Google, for example) that still support IE, or older versions of "evergreen" browsers that don't have native BigInt. |
Yup. You understood correctly. |
Related: #155
For the environments that have native bigint support, This PR will add an subpath export with a separate native bigint build(ESM). As far as I believe this shouldn't change/affect existing exports/builds. You can import the bigint build as follows:
memo: If this approach is acceptable, the
README.md
will need to be updated as well.