Skip to content

Commit 6c9edcf

Browse files
Use StructuredSerialize/StructuredDeserialize. For #170
1 parent f986b33 commit 6c9edcf

File tree

2 files changed

+174
-84
lines changed

2 files changed

+174
-84
lines changed

index.bs

Lines changed: 74 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@ spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/
2828
urlPrefix: dom.html
2929
type: interface
3030
text: Document; url: document
31-
urlPrefix: infrastructure.html
32-
type: abstract-op
33-
text: StructuredClone; url: structuredclone
34-
type: dfn
35-
text: cloneable objects; url: cloneable-objects
3631
spec: ecma262; urlPrefix: https://tc39.github.io/ecma262/
3732
type: dfn
3833
url: sec-algorithm-conventions
@@ -60,6 +55,7 @@ spec: ecma262; urlPrefix: https://tc39.github.io/ecma262/
6055
text: Promise; url: sec-promise-objects
6156
text: Realm; url: realm
6257
text: current Realm; url: current-realm
58+
text: Record; url: sec-list-and-record-specification-type
6359
spec: webidl; urlPrefix: https://heycam.github.io/webidl/
6460
type: dfn
6561
text: sequence<DOMString>; url: idl-sequence
@@ -566,13 +562,16 @@ transaction=] is running.
566562
<!-- ============================================================ -->
567563

568564
Each record is associated with a <dfn>value</dfn>. User agents must
569-
support any [=cloneable object=]. This includes simple types
565+
support any [=serializable object=]. This includes simple types
570566
such as [=String=] primitive values and [=Date=] objects as well as
571567
[=Object=] and [=Array=] instances, {{File}} objects, {{Blob}}
572568
objects, {{ImageData}} objects, and so on. Record [=/values=] are
573569
stored and retrieved by value rather than by reference; later changes
574570
to a value have no effect on the record stored in the database.
575571

572+
Record [=/values=] are [=/Records=] output by the
573+
<a abstract-op>StructuredSerialize</a> operation.
574+
576575

577576
<!-- ============================================================ -->
578577
<h3 id=key-construct>Keys</h3>
@@ -783,7 +782,7 @@ from a [=/value=]. A <dfn>valid key path</dfn> is one of:
783782
</aside>
784783

785784
[=/Key path=] values can only be accessed from properties explicitly
786-
copied by <a abstract-op>StructuredClone</a>, as well as the
785+
copied by <a abstract-op>StructuredSerialize</a>, as well as the
787786
following type-specific properties:
788787

789788
<table class=props>
@@ -2960,9 +2959,17 @@ when invoked, must run these steps:
29602959

29612960
9. Let |targetRealm| be a user-agent defined [=Realm=].
29622961

2963-
10. Let |clone| be <a abstract-op>StructuredClone</a>(|value|, |targetRealm|).
2962+
10. Let |clone| be a [=clone=] of |value| in |targetRealm|.
29642963
Rethrow any exceptions.
29652964

2965+
<details class=note>
2966+
<summary>Why create a copy of the value?</summary>
2967+
The value must be serialized when stored. Treating it as a copy
2968+
here allows other algorithms in this specification to treat it as
2969+
an ECMAScript value, but implementations may optimize this
2970+
if the difference in behavior is not observable.
2971+
</details>
2972+
29662973
11. If |store| uses [=in-line keys=], run these substeps:
29672974

29682975
1. Let |kpk| be the result of running the steps to [=extract a
@@ -3031,9 +3038,17 @@ when invoked, must run these steps:
30313038

30323039
9. Let |targetRealm| be a user-agent defined [=Realm=].
30333040

3034-
10. Let |clone| be <a abstract-op>StructuredClone</a>(|value|, |targetRealm|).
3041+
10. Let |clone| be a [=clone=] of |value| in |targetRealm|.
30353042
Rethrow any exceptions.
30363043

3044+
<details class=note>
3045+
<summary>Why create a copy of the value?</summary>
3046+
The value must be serialized when stored. Treating it as a copy
3047+
here allows other algorithms in this specification to treat it as
3048+
an ECMAScript value, but implementations may optimize this
3049+
if the difference in behavior is not observable.
3050+
</details>
3051+
30373052
11. If |store| uses [=in-line keys=], run these substeps:
30383053

30393054
1. Let |kpk| be the result of running the steps to [=extract a
@@ -4895,9 +4910,17 @@ invoked, must run these steps:
48954910

48964911
7. Let |targetRealm| be a user-agent defined [=Realm=].
48974912

4898-
8. Let |clone| be <a abstract-op>StructuredClone</a>(|value|, |targetRealm|).
4913+
8. Let |clone| be a [=clone=] of |value| in |targetRealm|.
48994914
Rethrow any exceptions.
49004915

4916+
<details class=note>
4917+
<summary>Why create a copy of the value?</summary>
4918+
The value must be serialized when stored. Treating it as a copy
4919+
here allows other algorithms in this specification to treat it as
4920+
an ECMAScript value, but implementations may optimize this
4921+
if the difference in behavior is not observable.
4922+
</details>
4923+
49014924
9. If the [=effective object store=] of this cursor uses [=in-line
49024925
keys=], run these substeps:
49034926

@@ -5766,6 +5789,23 @@ the implementation must run the following steps:
57665789

57675790
</div>
57685791

5792+
<!-- ============================================================ -->
5793+
<h3 id=clone-value>Clone a value</h3>
5794+
<!-- ============================================================ -->
5795+
5796+
<div class=algorithm>
5797+
5798+
To make a <dfn>clone</dfn> of |value| in |targetRealm|,
5799+
the implementation must run the following steps:
5800+
5801+
1. Let |serialized| be [=?=] <a abstract-op>StructuredSerialize</a>(|value|).
5802+
5803+
2. Let |clone| be [=?=] <a abstract-op>StructuredDeserialize</a>(|serialized|, |targetRealm|).
5804+
5805+
3. Return |clone|.
5806+
5807+
</div>
5808+
57695809

57705810
<!-- ============================================================ -->
57715811
<h2 id=database-operations>Database operations</h2>
@@ -5777,9 +5817,10 @@ These operations are run by the steps to [=asynchronously execute
57775817
a request=].
57785818

57795819
<aside class=note>
5780-
Invocations of <a abstract-op>StructuredClone</a>() in the operation steps below
5781-
can be asserted not to throw (as indicated by the [=!=] prefix)
5782-
because they operate only on previously cloned data.
5820+
Invocations of <a abstract-op>StructuredDeserialize</a>() in the operation
5821+
steps below can be asserted not to throw (as indicated by the [=!=] prefix)
5822+
because they operate only on previous output of
5823+
<a abstract-op>StructuredSerialize</a>().
57835824
</aside>
57845825

57855826
<!-- ============================================================ -->
@@ -5820,7 +5861,8 @@ follows.
58205861
to=] |key|, then remove the [=object-store/record=] from |store| using the
58215862
steps to [=delete records from an object store=].
58225863

5823-
4. Store a record in |store| containing |key| as its key and |value|
5864+
4. Store a record in |store| containing |key| as its key and
5865+
<a abstract-op>StructuredSerialize</a>(|value|)
58245866
as its value. The record is stored in the object store's
58255867
[=object-store/list of records=] such that the list is sorted
58265868
according to the key of the records in [=ascending=] order.
@@ -5903,9 +5945,9 @@ The steps to <dfn>retrieve a value from an object store</dfn> with
59035945

59045946
2. If |record| was not found, return undefined.
59055947

5906-
3. Let |value| be of |record|'s [=/value=].
5948+
3. Let |serialized| be of |record|'s [=/value=].
59075949

5908-
4. Return [=!=] <a abstract-op>StructuredClone</a>(|value|, |targetRealm|).
5950+
4. Return [=!=] <a abstract-op>StructuredDeserialize</a>(|serialized|, |targetRealm|).
59095951

59105952
</div>
59115953

@@ -5925,8 +5967,8 @@ store</dfn> with |targetRealm|, |store|, |range| and optional |count| are as fol
59255967

59265968
4. For each |record| in |records|, run these substeps:
59275969

5928-
1. Let |value| be |record|'s [=/value=].
5929-
2. Let |entry| be [=!=] <a abstract-op>StructuredClone</a>(|value|, |targetRealm|).
5970+
1. Let |serialized| be |record|'s [=/value=].
5971+
2. Let |entry| be [=!=] <a abstract-op>StructuredDeserialize</a>(|serialized|, |targetRealm|).
59305972
3. Append |entry| to |list|.
59315973

59325974
5. Return |list| converted to a [=sequence&lt;any&gt;=].
@@ -5989,9 +6031,9 @@ with |targetRealm|, |index| and |range| are as follows.
59896031

59906032
2. If |record| was not found, return undefined.
59916033

5992-
3. Let |value| be |record|'s [=referenced value=].
6034+
3. Let |serialized| be |record|'s [=referenced value=].
59936035

5994-
4. Return [=!=] <a abstract-op>StructuredClone</a>(|value|, |targetRealm|).
6036+
4. Return [=!=] <a abstract-op>StructuredDeserialize</a>(|serialized|, |targetRealm|).
59956037

59966038
</div>
59976039

@@ -6010,8 +6052,8 @@ index</dfn> with |targetRealm|, |index|, |range| and optional |count| are as fol
60106052

60116053
4. For each |record| in |records|, run these substeps:
60126054

6013-
1. Let |value| be |record|'s [=referenced value=].
6014-
2. Let |entry| be [=!=] <a abstract-op>StructuredClone</a>(|value|, |targetRealm|).
6055+
1. Let |serialized| be |record|'s [=referenced value=].
6056+
2. Let |entry| be [=!=] <a abstract-op>StructuredDeserialize</a>(|serialized|, |targetRealm|).
60156057
3. Append |entry| to |list|.
60166058

60176059
5. Return |list| converted to a [=sequence&lt;any&gt;=].
@@ -6285,9 +6327,9 @@ follows.
62856327

62866328
13. If |cursor|'s [=key only flag=] is unset, run these substeps:
62876329

6288-
1. Let |value| be |found record|'s [=referenced value=].
6330+
1. Let |serialized| be |found record|'s [=referenced value=].
62896331
2. Set |cursor|'s [=cursor/value=] to
6290-
[=!=] <a abstract-op>StructuredClone</a>(|value|, |targetRealm|)
6332+
[=!=] <a abstract-op>StructuredDeserialize</a>(|serialized|, |targetRealm|)
62916333

62926334
14. Set |cursor|'s [=got value flag=].
62936335

@@ -6432,7 +6474,7 @@ ECMAScript value or failure, or the steps may throw an exception.
64326474

64336475
<aside class=note>
64346476
Assertions can be made in the above steps because this algorithm is
6435-
only applied to values that are the output of <a abstract-op>StructuredClone</a>
6477+
only applied to values that are the output of <a abstract-op>StructuredDeserialize</a>
64366478
and only access "own" properties.
64376479
</aside>
64386480

@@ -6480,7 +6522,7 @@ true or false.
64806522

64816523
<aside class=note>
64826524
Assertions can be made in the above steps because this algorithm is
6483-
only applied to values that are the output of <a abstract-op>StructuredClone</a>.
6525+
only applied to values that are the output of <a abstract-op>StructuredDeserialize</a>.
64846526
</aside>
64856527

64866528
<div class=algorithm>
@@ -6528,7 +6570,7 @@ as follows. The algorithm takes a |value|, a |key| and a |keyPath|.
65286570

65296571
<aside class=note>
65306572
Assertions can be made in the above steps because this algorithm is
6531-
only applied to values that are the output of <a abstract-op>StructuredClone</a>,
6573+
only applied to values that are the output of <a abstract-op>StructuredDeserialize</a>,
65326574
and the steps to [=check that a key could be injected into a value=] have
65336575
been run.
65346576
</aside>
@@ -6961,7 +7003,7 @@ basic serialization concerns, serialized data could encode assumptions
69617003
which are not valid in newer versions of the user agent.
69627004

69637005
A practical example of this is the [=RegExp=] type. The <a
6964-
abstract-op>StructuredClone</a> operation allows cloning [=RegExp=]
7006+
abstract-op>StructuredSerialize</a> operation allows serializing [=RegExp=]
69657007
objects. A typical user agent will compile a regular expression into
69667008
native machine instructions, with assumptions about how the input data
69677009
is passed and results returned. If this internal state was serialized
@@ -7068,9 +7110,6 @@ document's Revision History</a>.
70687110
* Add non-normative documentation for every method.
70697111
(<a href="https://github.com/w3c/IndexedDB/issues/110">bug #110</a>)
70707112

7071-
* Use [[HTML]]'s <a abstract-op>StructuredClone</a> hook.
7072-
(<a href="https://github.com/w3c/IndexedDB/issues/135">bug #135</a>)
7073-
70747113
* Throw {{SecurityError}} if {{IDBFactory/open()}} or
70757114
{{IDBFactory/deleteDatabase()}} is called from an opaque origin.
70767115
(<a href="https://github.com/w3c/IndexedDB/issues/148">bug #148</a>)
@@ -7086,6 +7125,10 @@ document's Revision History</a>.
70867125
* Fix handling of edge cases in key generation algorithm.
70877126
(<a href="https://github.com/w3c/IndexedDB/issues/147">bug #147</a>)
70887127

7128+
* Use [[HTML]]'s <a abstract-op>StructuredSerialize</a> and
7129+
<a abstract-op>StructuredDeserialize</a> hooks.
7130+
(<a href="https://github.com/w3c/IndexedDB/issues/170">bug #170</a>)
7131+
70897132

70907133
<!-- ============================================================ -->
70917134
<h2 id=acknowledgements>Acknowledgements</h2>

0 commit comments

Comments
 (0)