#51885 patched a call site that threw an error but there were 2 others call that needed to be wrapped in the same way by a try/catch.
`initializeFully` is part of the calls in `responseWith(handleFetch)`.
Same #51885, throwing `SwCriticalError`allows the driver to fallback to `safeFetch` and ensure `responseWith` doesn't fail.
Fixes#50378
PR Close#51960
On Safari, the cache might fail on methods like `match` with an `Internal error`. Critical errors allows to fallback to `safeFetch()` in the `Driver`.
fixes: #50378
PR Close#51885
Currently internally Angular has some customized tsconfig files, because we don't align with the tsconfig of the rest of g3. These changes enable `noImplicitReturns` and `noPropertyAccessFromIndexSignature` to align better with the internal config.
PR Close#51728
This commit updates parts of the FW to be ES2022 complaint.
These changes are needed to fix the following problems problems with using properties before they are initialized.
Example
```ts
class Foo {
bar = this.buz;
constructor(private buz: unknown){}
}
```
PR Close#49559
This commit updates parts of the FW to be ES2022 complaint.
These changes are needed to fix the following problems problems with using properties before they are initialized.
Example
```ts
class Foo {
bar = this.buz;
constructor(private buz: unknown){}
}
```
PR Close#49332
* Updates circular dependency tests to use the `.mjs` outputs
* Switches away from CommonJS specific `require` calls.
* Simplifies the test helper logic since all browsers/NodeJS versions
support `URL` as a global.
PR Close#48521
Previously, when requesting non-cached asset resources from the network,
the ServiceWorker would strip off all request metadata (including
headers). This was done in order to avoid issues with opaque responses,
but it turned out to be overly aggressive, breaking/worsening legit
usecases (such as requesting compressed data).
This commit fixes this by preserving the headers of such requests.
For reference, Workbox passes the original request as is. (See for
example the [NetworkFirst][1] strategy).
> **Note**
> Data requests (i.e. requests for URLs that belong to a data-group) are
not affected by this. They already use the original resource as is.
[1]: 95f97a207f/packages/workbox-strategies/src/NetworkFirst.ts (L90)Fixes#24227
PR Close#47260
Previously, the `MockServerStateBuilder#withRedirect()` method did two
things: (a) define a redirect from one path to another and (b) specify
the contents of the redirect destination. This was confusing, because it
deviated from the regular way of specifying file contents, which is via
a `MockFileSystem` instance.
This commit slightly simplifies the process of defining redirects by
having the `withRedirect()` method only define the redirect and let the
contents of the redirect destination be specified as usual via
`MockFileSystem`. This makes `MockFileSystem` the single source of truth
for file contents used with `MockServerState`.
PR Close#47260
Previously, the default value of `MockRequest#credentials` (used in
testing) was set to `omit`. This was different than the default value
used in browsers, which is `same-origin` (see [Request docs on MDN][1])
and could lead to incorrect test results.
This commit changes the default value for `credentials` to `same-origin`
to match what would happen in the browser.
[1]: https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials
PR Close#47260
Previously, the criteria for determining if a request was a
[navigation request][1] did not account for the request method. This
incorrectly identified HTML form submit POST requests as navigation
requests and served `index.html` instead of passing them through to the
server, thus breaking the form submission.
This commit fixes this by ensuring that only GET requests are considered
navigation requests.
> **Note**
> HTML forms with their method set to `GET` will still be affected by
> the issue. This is not a big concern, because using `GET` for form
> submission is quite uncommon and generally discouraged (due to
> limitations and security considerations).
[1]: https://angular.io/guide/service-worker-config#handling-navigation-requestsFixes#36368
PR Close#47263
Since the `init` parameter has a default value of `{}`, it can never be
`!== undefined`. Thus, it is not necessary to account for that case.
PR Close#46912
Implement a new `notificationclick` action, `sendRequest`, which sends a
GET request to the specified URL, without opening a new window. This can
be useful for hitting an API endpoint.
PR Close#46912
.substr() is deprecated so we replace it with functions which work similarily but aren't deprecated
Signed-off-by: Tobias Speicher <rootcommander@gmail.com>
PR Close#45397
When the service worker checks for an update and finds that the version on the server is the same as
the version locally installed, it currently noops. This change introduces an event which it emits
in this situation which notifies clients a check has occurred without error and no update was found.
PR Close#45216
Add a new option for configuring data-groups, `cacheOpaqueResponses`,
that determines whether opaque responses are cached or not. This allows
greater flexibility in configuring the behavior of data-groups, while
still keeping the current defaults as fallbacks.
Fixes#44246
PR Close#44723
Make the `MockResponse` class used in tests behave more similarly to how
real responses work by making the following improvements:
- Use an empty `statusText` (`''`) when provided, instead of the default
`'OK'` value. This allows better representing opaque responses.
- Preserve more properties (`redirected`, `type`, `url`) when cloning a
`MockResponse`.
PR Close#44723
The `ng_rollup_bundle` rule has been replaced with a new rule called
`app_bundle`. This rule replicates the Angular v13 optimization
pipeline in the CLI, so that we can get better benchmarking results.
Also the rule is much simpler to maintain as it relies on ESbuild.
The old `ng_rollup_bundle` rule did rely on e.g. build-optimizer that no
longer has an effect on v13 Angular packages, so technically size
tests/symbol tests were no longer as correct as they were before. This
commit fixes that.
A couple of different changes and their explanation:
* Language-service will no longer use the benchmark rule for creating
its NPM bundles! It will use plain `rollup_bundle`. ESBuild would have
been nice but the language-service relies on AMD that ESBuild cannot
generate (yet?)
* Service-worker ngsw-worker.js file was generated using the benchmark
bundle rule. This is wrong. We will use a simple ESbuild rule in the
future. The output is more predictable that way, and we can have a
clear use of the benchmark bundle rule..
* A couple of benchmarks in `modules/` had to be updated to use e.g.
`initTableUtils` calls. This is done because with the new rule, all
files except for the entry-point are considered side-effect free. The
utilities for benchmarks relied on side-effects in some
transitively-loaded file (bad practice anyway IMO). We are now
initializing the utilities using a proper init function that is
exported...
PR Close#44490
When an app version is detected as broken, the SW calls the
`Driver#versionFailed()` method. Previously, this method would in turn
call the `Driver#sync()` method, which writes some metadata about the
SW's state to the `ngsw:/:db:contol` cache. More specifically,
`Driver#sync()` persists info about all known app versions, which one is
the latest and also what version each client is assigned to.
However, no relevant info is changed inside `Driver#versionFailed()`, so
the call to `Driver#sync()` is redundant (since there are no changes
that need to be synced with the cache). This is a left-over from
before #43518, when `Driver#versionFailed()` used to update version
assignments and thus did require synchronization with the cache.
This commit removes the redundant `Driver#sync()` call to avoid an
unnecessary write to the cache.
PR Close#43680
This commit introduces a new `SwUpdate#versionUpdates` observalbe, which provides more granular
information about Service Worker version updates than the already existing `SwUpdate#available`
observable.
The new events emitted by `SwUpdate#versionUpdates` basically add the possibility for application to
get notified if a new version is available on the server (not yet downloaded) and if an installation
of a new version failed.
Closes#39840
DEPRECATED: The `SwUpdate#availalbe` observable is deprecated.
The new `SwUpdate#versionUpdates` observable provides the same information and more. Therefore, it
is possible to rebuild the same behavior as `SwUpdate#availalbe` using the events emitted by
`SwUpdate#versionUpdates` and filtering for `VersionReadyEvent` events.
As a result, the `SwUpdate#availalbe` observable is now redundant.
PR Close#43668
Previously `activateUpdate` and `checkForUpdate` returned `Promise<void>`, which did not provide any
information of the actual outcome of the operation. Developers needed to subscribe to a
corresponding observable to obtain the outcome.
With this commit `SwUpdate#activateUpdate` will return `Promise<boolean>` which resolves to `true` if
an update was activated, to `false` if no new version is available and rejects in case of any error.
`SwUpdate#checkForUpdate` also returns a `Promise<boolean>` which resolves to `true` if an update is available, to `false` if no update was found and rejects in case of any error.
Closes#39840
BREAKING CHANGE: The return type of `SwUpdate#activateUpdate` and `SwUpdate#checkForUpdate` changed to `Promise<boolean>`.
Although unlikely, it is possible that this change will cause TypeScript type-checking to fail in
some cases. If necessary, update your types to account for the new
return type.
DEPRECATED: The `SwUpdate#activated` observable is deprecated.
The `SwUpdate#activated` observable only emits values as a direct response to calling
`SwUpdate#activateUpdate()` and was only useful for determining whether the call resulted in an
update or not. Now, the return value of `SwUpdate#activateUpdate()` can be used to determine the
outcome of the operation and therefore using `SwUpdate#activated` does not offer any benefit.
PR Close#43668
Previously, when a version was found to be broken, any clients assigned
to that version were unassigned (and either assigned to the latest
version or to none if the latest version was the broken one). A version
could be considered broken for several reasons, but most often it is a
response for a hashed asset that eiher does not exist or contains
different content than the SW expects. See
https://github.com/angular/angular/issues/28114#issuecomment-923122967
for more details.
However, assigning a client to a different version (or the network) in
the middle of a session, turned out to be more risky than keeping it on
the same version. For angular.io, for example, it has led to #28114.
This commit avoids making things worse when identifying a broken version
by keeping existing clients to their assigned version (but ensuring that
no new clients are assigned to the broken version).
NOTE:
Reloading the page generates a new client ID, so it is like a new client
for the SW, even if the tab and URL are the same.
PR Close#43518
Previously, a ServiceWorker test was using the
`MockServerState#sawRequestFor()` method. This method, however, only
returns a boolean indicating whether a request had been seen, but would
not throw an error in either case.
Since the intention was to assert that a specific request was made, this
commit switches to the correct `MockServerState#assertSawRequestFor()`
method.
PR Close#43518
Adds support for TypeScript 4.4. High-level overview of the changes made in this PR:
* Bumps the various packages to `typescript@4.4.2` and `tslib@2.3.0`.
* The `useUnknownInCatchVariables` compiler option has been disabled so that we don't have to cast error objects explicitly everywhere.
* TS now passes in a third argument to the `__spreadArray` call inside child class constructors. I had to update a couple of places in the runtime and ngcc to be able to pick up the calls correctly.
* TS now generates code like `(0, foo)(arg1, arg2)` for imported function calls. I had to update a few of our tests to account for it. See https://github.com/microsoft/TypeScript/pull/44624.
* Our `ngtsc` test setup calls the private `matchFiles` function from TS. I had to update our usage, because a new parameter was added.
* There was one place where we were setting the readonly `hasTrailingComma` property. I updated the usage to pass in the value when constructing the object instead.
* Some browser types were updated which meant that I had to resolve some trivial type errors.
* The downlevel decorators tranform was running into an issue where the Closure synthetic comments were being emitted twice. I've worked around it by recreating the class declaration node instead of cloning it.
PR Close#43281
In combination with the TS `noImplicitOverride` compatibility changes,
we also want to follow the best-practice of adding `override` to
members which are implemented as part of abstract classes. This
commit fixes all instances which will be flagged as part of the
custom `no-implicit-override-abstract` TSLint rule.
PR Close#42512
Previously, the ServiceWorker assumed that a client found in
`clientVersionMap` would exist (i.e. it could be retrieved via
`clients.get()`). However, if a browser tab had been closed, the
corresponding client (while present in `clientVersionMap`, which is only
updated on ServiceWorker initialization) would not be retrievable via
`clients.get()`.
This commit fixes it by checking whether the client exists before trying
to notify it about an unrecoverable state.
PR Close#42736
Previously, we used custom typings for the ServiceWorker environment.
This was necessary back when the ServiceWorker package was introduced,
since there were no official typings.
Since there are now official typings for Web Workers (including
ServiceWorkers) offered by TypeScript as [lib.webworker.d.ts][1], this
commit gets rid of our custom typings in favor of using the official
ones.
[1]: https://github.com/microsoft/TypeScript/blob/v4.3.4/lib/lib.webworker.d.ts
PR Close#42736
This commit better aligns the mock `ServiceWorkerGlobalScope`
implementation used in ServiceWorker tests (and the associated typings)
with the actual implementation (and the official TypeScript typings).
This allows verifying the ServiceWorker behavior in a slightly more
realistic environment.
This is in preparation of switching from our custom typings to the
official TypeScript typings (`lib.webworker.d.ts`).
PR Close#42736
This commit better aligns the mock client implementations used in
ServiceWorker tests (and the associated typings) with the actual
implementations (and the official TypeScript typings). This allows
verifying the ServiceWorker behavior in a slightly more realistic
environment.
This is in preparation of switching from our custom typings to the
official TypeScript typings (`lib.webworker.d.ts`).
PR Close#42736
In the ServiceWorker tests, we use mock implementations of the various
client APIs that the ServiceWorker interacts with. Previously, these
mock implementations were defined in the `testing/scope.ts` file. This
added several extra classes to a file that already contains a few,
making it harder to maintain.
Therefore, this commit moves these mock client classes to a separate
`testing/clients.ts` file.
PR Close#42736
This commit better aligns the mock event implementations used in
ServiceWorker tests (and the associated typings) with the actual
implementations (and the official TypeScript typings). This allows
verifying the ServiceWorker behavior in a slightly more realistic
environment.
This is in preparation of switching from our custom typings to the
official TypeScript typings (`lib.webworker.d.ts`).
PR Close#42736
In the ServiceWorker tests, we use mock implementations of the various
events emitted during the ServiceWorker lifecycle. Previously, these
mock implementations were defined in the `testing/scope.ts` file. This
added several extra classes to a file that already contains a few,
making it harder to maintain.
Therefore, this commit moves these mock event classes to a separate
`testing/events.ts` file.
PR Close#42736
This commit makes the `SwTestHarness.envIsSupported()` static method a
standalone function. This function is used to determine whether the
current environment provides the necessary APIs to run the SW tests and
is independent of `SwTestHarness`, so is no need for it to be a static
method of `SwTestHarness`.
This is in preparation of switching from our custom typings to the
official TypeScript typings (`lib.webworker.d.ts`).
PR Close#42736
This commit removes the duplicate `Context` interface and uses the
`ExtendableEvent` interface instead.
This is in preparation of switching from our custom typings to the
official TypeScript typings (`lib.webworker.d.ts`).
PR Close#42736
The ServiceWorker needs to keep track of some metadata for unhashed
asset resources to know if/when they might need to be revalidated. This
applies to resources that do not exist on the filesystem at build-time
(and thus cannot be hashed), such as fonts or images loaded from
external sources. For hashed resources, this metadata is irrelevant,
because the hash is enough to verify that the content hasn't changed and
no revalidation is necessary.
Previously, the ServiceWorker would store such metadata for hashed
resources as well, even though it would never be used (thus taking up
space unnecessarily).
This commit fixes it by not storing metadata for hashed resources, i.e.
those that are included in an asset-group's `hashes` array.
PR Close#42606
Previously, the SW was only able to clean up caches for app-versions
found in the `Driver`'s `versions` map. If (for some reason) the
`Driver` failed to load a valid stored state (including app-versions)
and ended up with an [empty `versions` map][1], any obsolete versions
would remain in the cache storage. This case was rare but possible.
This commit makes the cache clean-up logic more robust by ensuring that
all app-version caches are removed unless they are currently used by the
SW to serve active clients (with the exception of the latest
app-version, which is always retained).
Fixes#41728
[1]: 9de65dbdce/packages/service-worker/worker/src/driver.ts (L515-L529)
PR Close#42622
Previously, obsolete caches were only cleaned up when successfully
loading the stored state. When the state failed to be loaded, cleaning
up the caches would be skipped until the next SW initialization.
This commit changes this, ensuring that the caches are cleaned up
regardless if the stored state was loaded successfully or not.
PR Close#42622
This commit simplifies/systemizes accessing the `CacheStorage` through a
wrapper, with the following benefits:
- Ensuring a consistent cache name prefix is used for all caches
(without having to repeat the prefix in different places).
- Allowing referring to caches using their name without the common
cache name prefix.
- Exposing the cache name on cache instances, which for example makes it
easier to delete caches without having to keep track of the name used
to create them.
PR Close#42622
This commit improves the cache names generated by the ServiceWorker by
making them shorter and non-repetitive. In particular, the following
changes are made:
- Data-group cache names no longer include the `dynamic` infix, since it
does not add any value.
Before: `ngsw:<...>:data:dynamic:<...>`
After: `ngsw:<...>:data:<...>`
- `CacheDatabase` table names no longer include the `ngsw:<path>` prefix
twice.
Before: `ngsw:<path>:db:ngsw:<path>:<...>`
After: `ngsw:<path>:db:<...>`
NOTE 1:
This change will result in different cache names being generated for the
same app-versions with the new SericeWorker script. This means that some
of the previously cached data will need to be re-downloaded (because the
ServiceWorker will not be able to re-use the old caches), but that
should be transparent for the end user.
While possible, adding logic to allow the ServiceWorker to retrieve data
from the old caches is not worth the extra complecity and maintenance
cost.
NOTE 2:
Generating different cache names for some of the caches means that the
ServiceWorker will not be able to clean-up some of the old caches. This
will be taken care of in a subsequent commit that will rework the
clean-up logic to be more robust (covering changes such as this one and
other edgecases).
PR Close#42622
`CacheDatabase` uses the un-prefixed table names to interact with
database tables. However, the `list()` method returns the raw, prefixed
table names (which are not useful, since they cannot be used to
open/delete a table).
This commit fixes this by removing the prefix from the cache names
returned by the `list()` method.
NOTE:
This method is currently not used anywhere, so this change does not
affect the ServiceWorker behavior.
PR Close#42622