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

Definitions for W3C's Web Locks API - browser externs #4156

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
126 changes: 126 additions & 0 deletions externs/browser/w3c_web_locks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* Copyright 2024 The Closure Compiler Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @fileoverview Definitions for W3C's Web Locks API
* @see https://www.w3.org/TR/web-locks/
* @see https://www.w3.org/TR/2023/WD-web-locks-20230105/
*
* @externs
* @author [email protected] (Kuba Paczyński)
*/


/**
* @interface
* @see https://www.w3.org/TR/web-locks/#lockmanager
*/
var LockManager = function() {};


/**
* @param {string} name
* @param {!LockOptions|!LockGrantedCallback} options
* @param {!LockGrantedCallback|undefined=} callback
* @return {!Promise<void>}
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be either !Promise<*> or !Promise<?>, as https://www.w3.org/TR/web-locks/#api-lock-manager has this returning Promise<any>?

!Promise<*> seems safer as it forces people to typecast the result before using it, but OTOH https://github.com/microsoft/TypeScript/blob/main/src/lib/dom.generated.d.ts has Promise<any> which is equivalent to Promise<?>, and we're generally trying to maintain compatibility with the TS typings

*/
LockManager.prototype.request = function(name, options, callback) {};


/**
* @see https://www.w3.org/TR/web-locks/#dom-lockmanager-query
* @return {!Promise<!LockManagerSnapshot>}
*/
LockManager.prototype.query = function() {};


/**
* @interface
* @struct
* @see https://www.w3.org/TR/web-locks/#lock
*/
var Lock = function() {};


/**
* @see https://www.w3.org/TR/web-locks/#lock-concept-name
* @type {string}
*/
Lock.prototype.name;


/**
* @see https://www.w3.org/TR/web-locks/#lock-concept-mode
* @type {!LockMode}
*/
Lock.prototype.mode;


/**
* @typedef {function(!Lock): !Promise<void>}
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar to above, should this be !Promise<?> (or !Promise<*>)? https://www.w3.org/TR/web-locks/#api-lock-manager

* @see https://www.w3.org/TR/web-locks/#callbackdef-lockgrantedcallback
*/
var LockGrantedCallback;


/**
* Enum of:
* 'shared',
* 'exclusive',
* @typedef {string}
* @see https://www.w3.org/TR/web-locks/#enumdef-lockmode
*/
var LockMode;


/**
* @typedef {{
* mode : (!LockMode|undefined),
* ifAvailable : (boolean|undefined),
* steal : (boolean|undefined),
* signal : (!AbortSignal|undefined)
* }}
* @see https://www.w3.org/TR/web-locks/#dictdef-lockoptions
*/
var LockOptions;


/**
* @typedef {{
* mode : !LockMode,
Copy link
Contributor

Choose a reason for hiding this comment

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

From my understanding of the spec language, these should all be optional |undefined as they're not explicitly specified as required

https://webidl.spec.whatwg.org/#required-dictionary-member

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They are required, each member of LockInfo has defined non-nullable type and none is marked as optional - that is explicit requirement. LockInfo itself is then specified as non-nullable and not optional type in non-nullable and not optional sequence that defines both members of LockManagerSnapshot and thus making them also explicitly required. None in this chain can be optional or even undefined:

In the JavaScript binding, a value of undefined for the property corresponding to a dictionary member is treated the same as omitting that property.

Now those sequences of LockManagerSnapshot are zero-length by default (no locks held or pending) and can be zero-length at any point in time, but even then they are not optional. So putting in all together the promise of query() method not only cannot reject, but also when it resolves it must always resolve to LockManagerSnapshot with both members present, even if they are just empty arrays.

And so it does:

Screenshot 2024-02-29 at 23 56 15

* name : string,
* clientId : string,
* }}
* @see https://www.w3.org/TR/web-locks/#dictdef-lockinfo
*/
var LockInfo


/**
* @typedef {{
* held : !Array<!LockInfo>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment about |undefined as in LockInfo

* pending : !Array<!LockInfo>
* }}
* @see https://www.w3.org/TR/web-locks/#dictdef-lockmanagersnapshot
*/
var LockManagerSnapshot;


/**
* @type {!LockManager}
* @see https://w3c.github.io/keyboard-lock/#API
*/
Navigator.prototype.locks;
Loading