1 | ;
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 |
|
7 | var _MapStorage = require('./MapStorage');
|
8 |
|
9 | var _MapStorage2 = _interopRequireDefault(_MapStorage);
|
10 |
|
11 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
12 |
|
13 | /**
|
14 | * A specialization of the {@codelink MapStorage} storage mimicking the native
|
15 | * {@code WeakMap} using its internal garbage collector used once the size of
|
16 | * the storage reaches the configured threshold.
|
17 | */
|
18 | class WeakMapStorage extends _MapStorage2.default {
|
19 | /**
|
20 | * Initializes the storage.
|
21 | *
|
22 | * @param {{entryTtl: number}} config Weak map storage configuration. The
|
23 | * fields have the following meaning:
|
24 | * - entryTtl The time-to-live of a storage entry in milliseconds.
|
25 | */
|
26 | constructor(config) {
|
27 | super();
|
28 |
|
29 | /**
|
30 | * The time-to-live of a storage entry in milliseconds.
|
31 | *
|
32 | * @type {number}
|
33 | */
|
34 | this._entryTtl = config.entryTtl;
|
35 | }
|
36 |
|
37 | /**
|
38 | * @inheritdoc
|
39 | */
|
40 | has(key) {
|
41 | this._discardExpiredEntries();
|
42 |
|
43 | return super.has(key);
|
44 | }
|
45 |
|
46 | /**
|
47 | * @inheritdoc
|
48 | */
|
49 | get(key) {
|
50 | this._discardExpiredEntries();
|
51 |
|
52 | if (!super.has(key)) {
|
53 | return undefined;
|
54 | }
|
55 |
|
56 | return super.get(key).target;
|
57 | }
|
58 |
|
59 | /**
|
60 | * @inheritdoc
|
61 | */
|
62 | set(key, value) {
|
63 | this._discardExpiredEntries();
|
64 |
|
65 | return super.set(key, new WeakRef(value, this._entryTtl));
|
66 | }
|
67 |
|
68 | /**
|
69 | * @inheritdoc
|
70 | */
|
71 | delete(key) {
|
72 | this._discardExpiredEntries();
|
73 |
|
74 | return super.delete(key);
|
75 | }
|
76 |
|
77 | /**
|
78 | * @inheritdoc
|
79 | */
|
80 | keys() {
|
81 | this._discardExpiredEntries();
|
82 |
|
83 | return super.keys();
|
84 | }
|
85 |
|
86 | /**
|
87 | * @inheritdoc
|
88 | */
|
89 | size() {
|
90 | this._discardExpiredEntries();
|
91 |
|
92 | return super.size();
|
93 | }
|
94 |
|
95 | /**
|
96 | * Deletes all expired entries from this storage.
|
97 | */
|
98 | _discardExpiredEntries() {
|
99 | for (let key of super.keys()) {
|
100 | let targetReference = super.get(key);
|
101 | if (!targetReference.target) {
|
102 | // the reference has died
|
103 | super.delete(key);
|
104 | }
|
105 | }
|
106 | }
|
107 | }
|
108 |
|
109 | exports.default = WeakMapStorage; /**
|
110 | * A simple reference wrapper that emulates a weak reference. We seem to have
|
111 | * no other option, since WeakMap and WeakSet are not enumerable (so what is
|
112 | * the point of WeakMap and WeakSet if you still need to manage the keys?!) and
|
113 | * there is no native way to create a weak reference.
|
114 | */
|
115 |
|
116 | class WeakRef {
|
117 | /**
|
118 | * Initializes the weak reference to the target reference.
|
119 | *
|
120 | * @param {Object} target The target reference that should be referenced by
|
121 | * this weak reference.
|
122 | * @param {number} ttl The maximum number of milliseconds the weak
|
123 | * reference should be kept. The reference will be discarded once
|
124 | * ACCESSED after the specified timeout.
|
125 | */
|
126 | constructor(target, ttl) {
|
127 | if ($Debug) {
|
128 | if (!(target instanceof Object)) {
|
129 | throw new TypeError('The target reference must point to an object, ' + 'primitive values are not allowed');
|
130 | }
|
131 | if (ttl <= 0) {
|
132 | throw new Error('The time-to-live must be positive');
|
133 | }
|
134 | }
|
135 |
|
136 | /**
|
137 | * The actual target reference, or {@code null} if the reference has
|
138 | * been already discarded.
|
139 | *
|
140 | * @type {?Object}
|
141 | */
|
142 | this._reference = target;
|
143 |
|
144 | /**
|
145 | * The UNIX timestamp with millisecond precision marking the moment at
|
146 | * or after which the reference will be discarded.
|
147 | *
|
148 | * @type {number}
|
149 | */
|
150 | this._expiration = Date.now() + ttl;
|
151 | }
|
152 |
|
153 | /**
|
154 | * Returns the target reference, provided that the target reference is
|
155 | * still alive. Returns {@code null} if the reference has been discarded.
|
156 | *
|
157 | * @return {?Object} The target reference, or {@code null} if the reference
|
158 | * has been discarded by the garbage collector.
|
159 | */
|
160 | get target() {
|
161 | if (this._reference && Date.now() >= this._expiration) {
|
162 | this._reference = null; // let the GC do its job
|
163 | }
|
164 |
|
165 | return this._reference;
|
166 | }
|
167 | }
|
168 |
|
169 | typeof $IMA !== 'undefined' && $IMA !== null && $IMA.Loader && $IMA.Loader.register('ima/storage/WeakMapStorage', [], function (_export, _context) {
|
170 | ;
|
171 | return {
|
172 | setters: [],
|
173 | execute: function () {
|
174 | _export('default', exports.default);
|
175 | }
|
176 | };
|
177 | });
|