Additionally export storage.js from Minesweeper
This commit is contained in:
parent
55dd99512f
commit
13dcdd8237
53
Gruntfile.js
53
Gruntfile.js
|
@ -14,13 +14,33 @@ module.exports = grunt => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
focus: {
|
focus: {
|
||||||
dev: {
|
deploy: {
|
||||||
include: ["css", "js"],
|
include: ["css", "storage", "template"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
webpack: {
|
webpack: {
|
||||||
options: {
|
storage: {
|
||||||
entry: "./src/main/js/main.js",
|
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: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
|
@ -30,20 +50,14 @@ module.exports = grunt => {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: [".js"],
|
extensions: [".ts"],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
library: "fwdekker-template",
|
library: "fwdekker-template",
|
||||||
libraryTarget: "umd",
|
libraryTarget: "umd",
|
||||||
filename: "template.js",
|
filename: "template.js",
|
||||||
path: path.resolve(__dirname, "dist"),
|
path: path.resolve(__dirname, "dist"),
|
||||||
}
|
},
|
||||||
},
|
|
||||||
dev: {
|
|
||||||
mode: "development",
|
|
||||||
devtool: "inline-source-map",
|
|
||||||
},
|
|
||||||
deploy: {
|
|
||||||
mode: "production",
|
mode: "production",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -52,9 +66,13 @@ module.exports = grunt => {
|
||||||
files: ["src/main/**/*.css"],
|
files: ["src/main/**/*.css"],
|
||||||
tasks: ["cssmin"],
|
tasks: ["cssmin"],
|
||||||
},
|
},
|
||||||
js: {
|
storage: {
|
||||||
|
files: ["src/main/**/*.ts"],
|
||||||
|
tasks: ["webpack:storage"],
|
||||||
|
},
|
||||||
|
template: {
|
||||||
files: ["src/main/**/*.js"],
|
files: ["src/main/**/*.js"],
|
||||||
tasks: ["webpack:dev"],
|
tasks: ["webpack:template"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -65,9 +83,8 @@ module.exports = grunt => {
|
||||||
grunt.loadNpmTasks("grunt-focus");
|
grunt.loadNpmTasks("grunt-focus");
|
||||||
grunt.loadNpmTasks("grunt-webpack");
|
grunt.loadNpmTasks("grunt-webpack");
|
||||||
|
|
||||||
grunt.registerTask("dev", ["webpack:dev", "cssmin"]);
|
grunt.registerTask("deploy", ["webpack:storage", "webpack:template", "cssmin"]);
|
||||||
grunt.registerTask("dev:server", ["dev", "focus:dev"]);
|
grunt.registerTask("deploy:server", ["deploy", "focus:deploy"]);
|
||||||
grunt.registerTask("deploy", ["webpack:deploy", "cssmin"]);
|
|
||||||
|
|
||||||
grunt.registerTask("default", ["dev"]);
|
grunt.registerTask("default", ["deploy"]);
|
||||||
};
|
};
|
||||||
|
|
Binary file not shown.
12
package.json
12
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@fwdekker/template",
|
"name": "@fwdekker/template",
|
||||||
"version": "2.5.8",
|
"version": "2.6.0",
|
||||||
"description": "The base template for pages on fwdekker.com.",
|
"description": "The base template for pages on fwdekker.com.",
|
||||||
"author": "Florine W. Dekker",
|
"author": "Florine W. Dekker",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@ -19,9 +19,8 @@
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "grunt clean",
|
"clean": "grunt clean",
|
||||||
"dev": "grunt dev",
|
"deploy": "grunt deploy",
|
||||||
"dev:server": "grunt dev:server",
|
"deploy:server": "grunt deploy:server"
|
||||||
"deploy": "grunt deploy"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"milligram": "^1.4.1",
|
"milligram": "^1.4.1",
|
||||||
|
@ -35,7 +34,10 @@
|
||||||
"grunt-contrib-watch": "^1.1.0",
|
"grunt-contrib-watch": "^1.1.0",
|
||||||
"grunt-focus": "^1.0.0",
|
"grunt-focus": "^1.0.0",
|
||||||
"grunt-webpack": "^5.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"
|
"webpack-cli": "^4.9.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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};
|
|
@ -257,4 +257,4 @@ doAfterLoad(() => {
|
||||||
|
|
||||||
|
|
||||||
// Export to namespace
|
// Export to namespace
|
||||||
fwdekker = {stringToHtml, $, $a, doAfterLoad, nav, header, footer};
|
window.fwdekker = {stringToHtml, $, $a, doAfterLoad, nav, header, footer};
|
|
@ -47,5 +47,13 @@
|
||||||
|
|
||||||
<!--suppress HtmlUnknownTarget -->
|
<!--suppress HtmlUnknownTarget -->
|
||||||
<script src="../../dist/template.js"></script>
|
<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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2019",
|
||||||
|
"strict": true,
|
||||||
|
"rootDir": "./src/main/js/",
|
||||||
|
"outDir": "./dist/js/"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/main/js/**/*.ts"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue