| 119 | * Unsaved data can also be recovered locally for poor network conditions/unexpected shutdown |
| 120 | */ |
| 121 | export class BufferStorage { |
| 122 | static bufferStorageNamespace = `${LS_DATASHEET_NAMESPACE}.opBuffer`; |
| 123 | static pendingChangesetsNamespace = `${LS_DATASHEET_NAMESPACE}.localChangeset`; |
| 124 | |
| 125 | // localStorage encapsulates the instance and binds the namespace in advance |
| 126 | // https://github.com/nbubna/store |
| 127 | private opBufferStorage = this.lsStore.namespace(BufferStorage.bufferStorageNamespace); |
| 128 | private _opBuffer: IOperation[] = []; |
| 129 | |
| 130 | private localPendingChangesetStorage = this.lsStore.namespace(BufferStorage.pendingChangesetsNamespace); |
| 131 | private _localPendingChangeset: ILocalChangeset | undefined; |
| 132 | |
| 133 | constructor(public resourceId: string, public resourceType: ResourceType, public lsStore: ILsStore) { |
| 134 | this.resumeLocalState(); |
| 135 | } |
| 136 | |
| 137 | // The cache has just been created, but it is still queuing operations that have not been sent out |
| 138 | // After sending, the op in opBuffer will be assembled into localPendingChangeset |
| 139 | get opBuffer(): IOperation[] { |
| 140 | return this._opBuffer; |
| 141 | } |
| 142 | |
| 143 | set opBuffer(value: IOperation[]) { |
| 144 | this._opBuffer = value; |
| 145 | if (value == null || value.length === 0) { |
| 146 | this.opBufferStorage.remove(this.resourceId); |
| 147 | return; |
| 148 | } |
| 149 | try { |
| 150 | this.opBufferStorage.set(this.resourceId, value); |
| 151 | } catch (e) { |
| 152 | console.error(e); |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | // has been sent, waiting for ACK changeset |
| 157 | get localPendingChangeset(): ILocalChangeset | undefined { |
| 158 | return this._localPendingChangeset; |
| 159 | } |
| 160 | |
| 161 | set localPendingChangeset(value: ILocalChangeset | undefined) { |
| 162 | this._localPendingChangeset = value; |
| 163 | if (value == null) { |
| 164 | this.localPendingChangesetStorage.remove(this.resourceId); |
| 165 | return; |
| 166 | } |
| 167 | try { |
| 168 | this.localPendingChangesetStorage.set(this.resourceId, value); |
| 169 | } catch (e) { |
| 170 | // When setting localStorage fails, clear the original value. |
| 171 | this.localPendingChangesetStorage.remove(this.resourceId); |
| 172 | console.error(e); |
| 173 | } |
| 174 | } |
| 175 | /** |
| 176 | * @description reads the data of opBuffer and clears the opBuffer, |
| 177 | * Considering the delay of the network layer, the front end cannot receive the ack in time, |
| 178 | * here will save a copy of the opsBuffer data in the storage |