Additionally export storage.js from Minesweeper

This commit is contained in:
Florine W. Dekker 2022-03-26 19:33:42 +01:00
parent 55dd99512f
commit 13dcdd8237
Signed by: FWDekker
GPG Key ID: D3DCFAA8A4560BE0
7 changed files with 248 additions and 24 deletions

View File

@ -14,13 +14,33 @@ module.exports = grunt => {
},
},
focus: {
dev: {
include: ["css", "js"],
deploy: {
include: ["css", "storage", "template"],
},
},
webpack: {
options: {
entry: "./src/main/js/main.js",
storage: {
entry: "./src/main/js/Storage.ts",
module: {
rules: [
{
test: /\.ts$/,
use: "ts-loader",
exclude: /node_modules/,
},
],
},
resolve: {
extensions: [".ts"],
},
output: {
filename: "storage.js",
path: path.resolve(__dirname, "dist/"),
},
mode: "production",
},
template: {
entry: "./src/main/js/template.js",
module: {
rules: [
{
@ -30,20 +50,14 @@ module.exports = grunt => {
],
},
resolve: {
extensions: [".js"],
extensions: [".ts"],
},
output: {
library: "fwdekker-template",
libraryTarget: "umd",
filename: "template.js",
path: path.resolve(__dirname, "dist"),
}
},
dev: {
mode: "development",
devtool: "inline-source-map",
},
deploy: {
},
mode: "production",
},
},
@ -52,9 +66,13 @@ module.exports = grunt => {
files: ["src/main/**/*.css"],
tasks: ["cssmin"],
},
js: {
storage: {
files: ["src/main/**/*.ts"],
tasks: ["webpack:storage"],
},
template: {
files: ["src/main/**/*.js"],
tasks: ["webpack:dev"],
tasks: ["webpack:template"],
},
},
});
@ -65,9 +83,8 @@ module.exports = grunt => {
grunt.loadNpmTasks("grunt-focus");
grunt.loadNpmTasks("grunt-webpack");
grunt.registerTask("dev", ["webpack:dev", "cssmin"]);
grunt.registerTask("dev:server", ["dev", "focus:dev"]);
grunt.registerTask("deploy", ["webpack:deploy", "cssmin"]);
grunt.registerTask("deploy", ["webpack:storage", "webpack:template", "cssmin"]);
grunt.registerTask("deploy:server", ["deploy", "focus:deploy"]);
grunt.registerTask("default", ["dev"]);
grunt.registerTask("default", ["deploy"]);
};

BIN
package-lock.json generated

Binary file not shown.

View File

@ -1,6 +1,6 @@
{
"name": "@fwdekker/template",
"version": "2.5.8",
"version": "2.6.0",
"description": "The base template for pages on fwdekker.com.",
"author": "Florine W. Dekker",
"license": "MIT",
@ -19,9 +19,8 @@
],
"scripts": {
"clean": "grunt clean",
"dev": "grunt dev",
"dev:server": "grunt dev:server",
"deploy": "grunt deploy"
"deploy": "grunt deploy",
"deploy:server": "grunt deploy:server"
},
"dependencies": {
"milligram": "^1.4.1",
@ -35,7 +34,10 @@
"grunt-contrib-watch": "^1.1.0",
"grunt-focus": "^1.0.0",
"grunt-webpack": "^5.0.0",
"webpack": "^5.69.1",
"ts-loader": "^9.2.8",
"ts-node": "^10.7.0",
"typescript": "^4.6.3",
"webpack": "^5.70.0",
"webpack-cli": "^4.9.2"
}
}

186
src/main/js/Storage.ts Normal file
View File

@ -0,0 +1,186 @@
/**
* Stores key-value pairs.
*/
export interface Storage {
/**
* Removes the data from storage.
*/
clear(): void
/**
* Retrieves an array from storage.
*
* @param name the name of the array to retrieve
* @param def the value to return if no array is stored with the given name
*/
getArray(name: string, def: any[]): any[]
/**
* Stores an array.
*
* @param name the name of the array to store
* @param value the array to store under the given name
* @protected
*/
setArray(name: string, value: any[]): void
/**
* Retrieves a boolean from storage.
*
* @param name the name of the boolean to retrieve
* @param def the value to return if no boolean is stored with the given name
* @protected
*/
getBoolean(name: string, def: boolean): boolean
/**
* Stores a boolean.
*
* @param name the name of the boolean to store
* @param value the boolean to store under the given name
* @protected
*/
setBoolean(name: string, value: boolean): void
/**
* Retrieves a number from storage.
*
* @param name the name of the number to retrieve
* @param def the value to return if no number is stored with the given name
* @protected
*/
getNumber(name: string, def: number): number
/**
* Stores a number.
*
* @param name the name of the number to store
* @param value the number to store under the given name
* @protected
*/
setNumber(name: string, value: number): void
}
/**
* Stores key-value pairs in a single entry in `localStorage`.
*/
export class LocalStorage implements Storage {
private readonly key: string;
private cache: { [key: string]: string } | null = null;
/**
* Constructs a new persistent storage item under the given key.
*
* @param key the unique identifier to store the data under
*/
constructor(key: string) {
this.key = key;
}
/**
* Reads the object stored in local storage.
*
* @return the object stored in local storage, or an empty object if there is nothing in the local storage
* @private
*/
private read(): { [key: string]: string } {
if (this.cache === null)
this.cache = JSON.parse(localStorage.getItem(this.key) ?? "{}");
return this.cache!;
}
/**
* Writes the given object to local storage.
*
* @param item the object to write to local storage
* @private
*/
private write(item: { [key: string]: string }): void {
this.cache = item;
localStorage.setItem(this.key, JSON.stringify(item));
}
clear(): void {
this.cache = null;
localStorage.removeItem(this.key);
}
getArray(name: string, def: any[] = []): any[] {
const array = this.read()[name];
return array === undefined ? def : JSON.parse(array);
}
setArray(name: string, value: any[]): void {
const item = this.read();
item[name] = JSON.stringify(value);
this.write(item);
}
getBoolean(name: string, def: boolean = false): boolean {
return (this.read()[name] ?? `${def}`) === "true";
}
setBoolean(name: string, value: boolean): void {
const item = this.read();
item[name] = "" + value;
this.write(item);
}
getNumber(name: string, def: number = 0): number {
return +(this.read()[name] ?? def);
}
setNumber(name: string, value: number): void {
const item = this.read();
item[name] = "" + value;
this.write(item);
}
}
/**
* Stores key-value pairs in an object.
*/
export class MemoryStorage implements Storage {
private storage: { [key: string]: any } = {};
clear(): void {
this.storage = {};
}
setArray(name: string, value: any[] = []): void {
this.storage[name] = value;
}
getArray(name: string, def: any[]): any[] {
return this.storage[name] ?? def;
}
setBoolean(name: string, value: boolean): void {
this.storage[name] = value;
}
getBoolean(name: string, def: boolean): boolean {
return this.storage[name] ?? def;
}
setNumber(name: string, value: number): void {
this.storage[name] = value;
}
getNumber(name: string, def: number): number {
return this.storage[name] ?? def;
}
}
// @ts-ignore
if (typeof window.fwdekker === "undefined")
// @ts-ignore
window.fwdekker = {};
// @ts-ignore
window.fwdekker.storage = {Storage, LocalStorage, MemoryStorage};

View File

@ -257,4 +257,4 @@ doAfterLoad(() => {
// Export to namespace
fwdekker = {stringToHtml, $, $a, doAfterLoad, nav, header, footer};
window.fwdekker = {stringToHtml, $, $a, doAfterLoad, nav, header, footer};

View File

@ -47,5 +47,13 @@
<!--suppress HtmlUnknownTarget -->
<script src="../../dist/template.js"></script>
<script src="../../dist/storage.js"></script>
<script>
const storage = new fwdekker.storage.MemoryStorage();
storage.setNumber("test-key", 11);
console.log("Expected: 11. Actual: " + storage.getNumber("test-key", 0) + ".");
</script>
</body>
</html>

11
tsconfig.json Normal file
View File

@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "es2019",
"strict": true,
"rootDir": "./src/main/js/",
"outDir": "./dist/js/"
},
"include": [
"src/main/js/**/*.ts"
]
}