Skip to content
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

[spec] Web Locks integration: support navigator.locks in the worklet #209

Merged
merged 4 commits into from
Dec 16, 2024
Merged
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
75 changes: 72 additions & 3 deletions spec.bs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ spec:infra;
spec:webidl;
type:interface;
text:double
text:long
type:dfn;
text:an exception was thrown
spec:html;
Expand Down Expand Up @@ -94,6 +95,10 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
spec: beacon; urlPrefix: https://w3c.github.io/beacon/
type: dfn
text: beacon; url: beacon
spec: web-locks; urlPrefix: https://w3c.github.io/web-locks/
type: dfn
text: lock manager; url: lock-manager
text: obtain a lock manager; url: obtain-a-lock-manager
spec: ecma; urlPrefix: https://tc39.es/ecma262/
type: dfn
text: call; url: sec-call
Expand Down Expand Up @@ -844,6 +849,8 @@ Moreover, each {{SharedStorageWorklet}}'s [=global scopes|list of global scopes=
readonly attribute PrivateAggregation privateAggregation;

Promise<sequence<StorageInterestGroup>> interestGroups();

readonly attribute SharedStorageWorkletNavigator navigator;
};
</xmp>

Expand All @@ -853,7 +860,10 @@ Moreover, each {{SharedStorageWorklet}}'s [=global scopes|list of global scopes=

Each {{SharedStorageWorkletGlobalScope}} also has an associated <dfn for=SharedStorageWorkletGlobalScope>operation map</dfn>, which is a [=map=], initially empty, of [=strings=] (denoting operation names) to [=function objects=].

Each {{SharedStorageWorkletGlobalScope}} also has an associated {{SharedStorage}} instance, with the [=SharedStorageWorkletGlobalScope/sharedStorage getter=] algorithm as described below.
Each {{SharedStorageWorkletGlobalScope}} has an associated {{SharedStorage}} instance <dfn for=SharedStorageWorkletGlobalScope>shared storage instance</dfn>.

Each {{SharedStorageWorkletGlobalScope}} has an associated {{SharedStorageWorkletNavigator}} instance <dfn for=SharedStorageWorkletGlobalScope>navigator instance</dfn>.


### {{SharedStorageWorkletGlobalScope}} algorithms ### {#scope-algo}
<div algorithm>
Expand Down Expand Up @@ -892,9 +902,16 @@ Moreover, each {{SharedStorageWorklet}}'s [=global scopes|list of global scopes=
</div>

<div algorithm>
The <dfn for="SharedStorageWorkletGlobalScope">{{SharedStorageWorkletGlobalScope/sharedStorage}} getter</dfn> steps are:
The <dfn attribute for=SharedStorageWorkletGlobalScope>sharedStorage</dfn> [=getter steps=] are:

1. If [=this=]'s [=addModule success=] is true, return [=this=]'s [=SharedStorageWorkletGlobalScope/shared storage instance=].
1. Otherwise, throw a {{TypeError}}.
</div>

<div algorithm>
The <dfn attribute for=SharedStorageWorkletGlobalScope>navigator</dfn> [=getter steps=] are:

1. If [=this=]'s [=addModule success=] is true, return [=this=]'s {{SharedStorageWorkletGlobalScope/sharedStorage}}.
1. If [=this=]'s [=addModule success=] is true, return [=this=]'s [=SharedStorageWorkletGlobalScope/navigator instance=].
1. Otherwise, throw a {{TypeError}}.
</div>

Expand Down Expand Up @@ -2024,6 +2041,58 @@ The IDL attribute {{HTMLSharedStorageWritableElementUtils/sharedStorageWritable}
1. Return |parameters|[|paramKey|].
</div>

# Web Locks Integration # {#web-locks-integration}

## User Agent Associated State ## {#user-agent-associated-state}

A <dfn>shared storage lock managers map</dfn> is a [=map=] of [=/origins=] to [=lock managers=]. It is initially empty.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think this should key on origin here. At a minimum it should use storage-key instead:

https://storage.spec.whatwg.org/#storage-key

That way when partitioning is added to the storage key this spec will automatically work correctly.

But you should also consider maybe using the storage bottle map stuff that the web locks spec uses?

https://w3c.github.io/web-locks/#obtain-a-lock-manager

Copy link
Collaborator Author

@xyaoinum xyaoinum Dec 5, 2024

Choose a reason for hiding this comment

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

Shared storage defines its own shared storage shed, which is a map from origins to storage shelves.

Special-casing the obtain a storage bottle map algorithm could work (i.e, if it's a Shared Storage environment, use the shelf from shared storage shed). However, as I remember, the Web Locks & Storage Buckets owners preferred just using a standalone LockManager for Shared Storage to avoid potential side effects (e.g., calling [=obtain a local storage bottle map=] may have other redundancies that Shared Storage doesn't care).

However, I'm unsure if this preference on implementation still applies at the specification level.

@inexorabletash / @ayuishii: Could you weigh in on this? (also cc'ing @evanstade, though it looks he's currently unavailable)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Is the origin key because shared storage cannot be used from a partitioned context? Its only ever usable from the top-level? (I think there have been some proposals around partitioned top-level contexts, so not sure we should depend on that at the spec level.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Shared storage can be written in any context, but the read can only be from 'shared storage worklets', and the only way data can leave these worklets is via some privacy-preserving APIs.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Right, I remember now. Shared storage effectively bypasses partitioning by design and is constrained by the privacy gates.

Copy link
Member

Choose a reason for hiding this comment

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

My memory here is hazy, so I don't remember any specific objections. Special casing "obtain a storage bottle map" seems reasonable if the Storage owners are okay with it, since it wouldn't require any changes in Web Locks itself which sounds like the right layering?

Tagging in @saschanaz too for spec thoughts.


A [=user agent=] has an associated [=shared storage lock managers map=].

Note: Similar to its data partitioning, the shared storage has its own lock management scope, independent of the Storage Buckets API. These web locks will not interact with web locks created from Window or Worker via the existing, legacy Web Locks API.

## {{SharedStorageWorkletNavigator}} interface ## {#shared-storage-worklet-navigator-interface}

<xmp class='idl'>
[
Exposed=SharedStorageWorklet,
] interface SharedStorageWorkletNavigator {};
</xmp>

## Web Locks IDLs Monkey Patches ## {#web-locks-api-monkey-patches}

Include the {{NavigatorLocks}} mixin in {{SharedStorageWorkletNavigator}} (i.e., let {{SharedStorageWorkletNavigator}} contain a {{LockManager}} instance):

<xmp class='idl'>
SharedStorageWorkletNavigator includes NavigatorLocks;
</xmp>

The {{LockManager}} and {{Lock}} are additionally exposed to SharedStorageWorklet:

<xmp class='idl'>
[SecureContext, Exposed=(Window,Worker,SharedStorageWorklet)]
interface LockManager {};
</xmp>

<xmp class='idl'>
[SecureContext, Exposed=(Window,Worker,SharedStorageWorklet)]
interface Lock {};
</xmp>

## Monkey Patch for lock manager's description ## {#monkey-patch-for-lock-manager-description}

Add the following sentence at the end of the paragraph that defines [=lock manager=]: "Additionally, each user agent includes one [=shared storage lock managers map=] for Web Locks API's integration with the Shared Storage API."

## Monkey Patch for the "obtain a lock manager" algorithm ## {#monkey-patch-for-the-obtain-a-lock-manager-algorithm}

The [=obtain a lock manager=] algorithm should be prepended with the following steps:

<div algorithm='monkey-patch-obtain-a-lock-manager'>
1. If [=current realm=]'s [=global object=] is a {{SharedStorageWorkletGlobalScope}}:
1. Let |workletDataOrigin| be <var ignore=''>environment</var>'s [=environment settings object/origin=].
1. Return [=shared storage lock managers map=][|workletDataOrigin|].
xyaoinum marked this conversation as resolved.
Show resolved Hide resolved
</div>

Permissions Policy Integration {#permission}
============================================

Expand Down