diff --git a/packages/client-flutter/lib/app/core.dart b/packages/client-flutter/lib/app/core.dart index 3e9b8be..8b04452 100644 --- a/packages/client-flutter/lib/app/core.dart +++ b/packages/client-flutter/lib/app/core.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter_js/extensions/fetch.dart'; import 'package:sqflite_common_ffi/sqflite_ffi.dart'; import 'package:path/path.dart'; @@ -122,7 +123,6 @@ class AppCore extends InheritedWidget { final cascade = Cascade().add(shelf_router.Router()..post('/', updateRes)); - // TODO: Set this to false before every release - if (true) await shelf_io.serve(logRequests().addHandler(cascade.handler), InternetAddress.anyIPv4, 4578); + if (kDebugMode) await shelf_io.serve(logRequests().addHandler(cascade.handler), InternetAddress.anyIPv4, 4578); } } \ No newline at end of file diff --git a/packages/core/.gitignore b/packages/core/.gitignore index 11ddd8d..8131fee 100644 --- a/packages/core/.gitignore +++ b/packages/core/.gitignore @@ -1,3 +1,4 @@ node_modules # Keep environment variables out of version control .env +pack/database \ No newline at end of file diff --git a/packages/core/pack/plugins.js b/packages/core/pack/plugins.js new file mode 100644 index 0000000..2c6adac --- /dev/null +++ b/packages/core/pack/plugins.js @@ -0,0 +1,4 @@ +export default [ + ...require('./polyfill/index'), + require('./database/index'), +] \ No newline at end of file diff --git a/packages/core/pack/polyfill/index.js b/packages/core/pack/polyfill/index.js new file mode 100644 index 0000000..ba1892e --- /dev/null +++ b/packages/core/pack/polyfill/index.js @@ -0,0 +1,3 @@ +export default [ + require('./timeout') +] \ No newline at end of file diff --git a/packages/core/pack/polyfill/timeout.js b/packages/core/pack/polyfill/timeout.js new file mode 100644 index 0000000..44a953c --- /dev/null +++ b/packages/core/pack/polyfill/timeout.js @@ -0,0 +1,51 @@ +const webpack = require('webpack'); + +var __polyfillTimeout_timers = {}; +function __polyfillTimeout_generateNewId() { + var r = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); + while (__polyfillTimeout_timers.hasOwnProperty(r)) { // check weather the id already exists + r = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); + } + return r; +} + + +function __polyfillTimeout_check() { + if (Object.keys(__polyfillTimeout_timers).length <= 0) return; + + var t = Date.now(); + for (var timerId in __polyfillTimeout_timers) { + if (__polyfillTimeout_timers.hasOwnProperty(timerId) && t > __polyfillTimeout_timers[timerId].time) { + __polyfillTimeout_timers[timerId].callback(); + clearTimeout(timerId); + } + } + requestIdleCallback(__polyfillTimeout_check); +} + + +function _setTimeout(callback, delay) { + if (typeof(callback) != 'function') throw new Error("callback should be a function"); + if (typeof(delay) != 'number' || delay < 0) throw new Error("delay should be a positive number"); + var newId = __polyfillTimeout_generateNewId(); + __polyfillTimeout_timers[newId] = { + callback: callback, + time: Date.now() + delay + }; + if (Object.keys(__polyfillTimeout_timers).length == 1) { + requestIdleCallback(__polyfillTimeout_check); + } + return newId; +} + +function _clearTimeout(id) { + if (__polyfillTimeout_timers.hasOwnProperty(id)) delete __polyfillTimeout_timers[id]; +} + +export default timeout = new webpack.DefinePlugin({ + __polyfillTimeout_timers, + __polyfillTimeout_generateNewId, + __polyfillTimeout_check, + setTimeout: _setTimeout, + clearTimeout: _clearTimeout, +}) \ No newline at end of file diff --git a/packages/core/package.json b/packages/core/package.json index e6130b9..587a660 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -24,6 +24,7 @@ "webpack-cli": "^5.1.4" }, "dependencies": { + "@prisma/client": "5.2.0", "@types/uuid": "^8.3.4", "core-js": "^3.32.2", "locale-codes": "^1.3.1", diff --git a/packages/core/prisma/dev.db b/packages/core/prisma/dev.db new file mode 100644 index 0000000..ff240a6 Binary files /dev/null and b/packages/core/prisma/dev.db differ diff --git a/packages/core/prisma/dev.db-journal b/packages/core/prisma/dev.db-journal new file mode 100644 index 0000000..a64a5a9 Binary files /dev/null and b/packages/core/prisma/dev.db-journal differ diff --git a/packages/core/prisma/migrations/20230909231306_refracture/migration.sql b/packages/core/prisma/migrations/20230909231306_refracture/migration.sql new file mode 100644 index 0000000..5c91060 --- /dev/null +++ b/packages/core/prisma/migrations/20230909231306_refracture/migration.sql @@ -0,0 +1,48 @@ +-- CreateTable +CREATE TABLE "Track" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "title" TEXT NOT NULL, + "duration" BIGINT NOT NULL, + "track_number" INTEGER NOT NULL, + CONSTRAINT "Track_id_fkey" FOREIGN KEY ("id") REFERENCES "Collection" ("id") ON DELETE RESTRICT ON UPDATE CASCADE +); + +-- CreateTable +CREATE TABLE "Artist" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "profile_image" TEXT NOT NULL, + "name" TEXT NOT NULL, + "biography" TEXT NOT NULL +); + +-- CreateTable +CREATE TABLE "User" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "profile_image" TEXT NOT NULL, + "name" TEXT NOT NULL +); + +-- CreateTable +CREATE TABLE "Collection" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "title" TEXT NOT NULL, + "art" TEXT, + "year" INTEGER, + "duration" BIGINT NOT NULL, + CONSTRAINT "Collection_id_fkey" FOREIGN KEY ("id") REFERENCES "Artist" ("id") ON DELETE RESTRICT ON UPDATE CASCADE, + CONSTRAINT "Collection_id_fkey" FOREIGN KEY ("id") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE +); + +-- CreateTable +CREATE TABLE "_ArtistToTrack" ( + "A" INTEGER NOT NULL, + "B" INTEGER NOT NULL, + CONSTRAINT "_ArtistToTrack_A_fkey" FOREIGN KEY ("A") REFERENCES "Artist" ("id") ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT "_ArtistToTrack_B_fkey" FOREIGN KEY ("B") REFERENCES "Track" ("id") ON DELETE CASCADE ON UPDATE CASCADE +); + +-- CreateIndex +CREATE UNIQUE INDEX "_ArtistToTrack_AB_unique" ON "_ArtistToTrack"("A", "B"); + +-- CreateIndex +CREATE INDEX "_ArtistToTrack_B_index" ON "_ArtistToTrack"("B"); diff --git a/packages/core/prisma/migrations/migration_lock.toml b/packages/core/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000..e5e5c47 --- /dev/null +++ b/packages/core/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "sqlite" \ No newline at end of file diff --git a/packages/core/prisma/schema.prisma b/packages/core/prisma/schema.prisma index dca3252..3a4a4bb 100644 --- a/packages/core/prisma/schema.prisma +++ b/packages/core/prisma/schema.prisma @@ -11,24 +11,37 @@ datasource db { } model Track { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) title String duration BigInt - artists Artist[] @relation(fields: [name], references: [id]) - album Album @relation(fields: [title, art], references: [id]) + artists Artist[] @relation + album Collection @relation(fields: [id], references: [id]) track_number Int } model Artist { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) profile_image String name String - tracks Track[] @relation(fields: [title, duration, artists, album], references: [id]) + biography String + tracks Track[] + albums Collection[] @relation } -model Album { - id Int @id @default(autoincrement()) +model User { + id Int @id @default(autoincrement()) + profile_image String + name String + playlists Collection[] @relation +} + +model Collection { + id Int @id @default(autoincrement()) title String - art String - artist Artist @relation(fields: [name], references: [id]) + art String? + artist Artist? @relation(fields: [id], references: [id]) + user User? @relation(fields: [id], references: [id]) + year Int? + duration BigInt + tracks Track[] } \ No newline at end of file diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index acbf265..dd62256 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,5 +1,6 @@ import 'react-native-polyfill'; import 'core-js/actual/url'; + import { AccountManager, AccountClass } from './account/index'; import { ItemManager } from './media/index'; import Player from './player/index'; diff --git a/packages/core/src/storage/index.ts b/packages/core/src/storage/index.ts index 306122b..1fc23bf 100644 --- a/packages/core/src/storage/index.ts +++ b/packages/core/src/storage/index.ts @@ -1,4 +1,5 @@ import { RawData } from "../plugin/index"; +import { PrismaClient } from '@prisma/client' interface ConnectionData { address: string @@ -7,7 +8,9 @@ interface ConnectionData { declare const connection_data: ConnectionData export class Database { - address: URL; + public internal = new PrismaClient({ log: [{ level: 'query', emit: 'event' }] }); + + protected server_address?: URL; /** * Requests @@ -19,7 +22,11 @@ export class Database { } constructor () { - this.address = new URL(connection_data.address); + this.internal.$on('query', (query) => { + sendMessage('query', JSON.stringify(query)); + }) + + if (connection_data) this.server_address = new URL(connection_data.address); } } diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 5a2fe2f..2e32825 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "esModuleInterop": true, - "target": "ES2020" + "target": "ES2020", + "module": "NodeNext" } } \ No newline at end of file diff --git a/packages/core/webpack.config.js b/packages/core/webpack.config.js index 4eb0c35..99087cf 100644 --- a/packages/core/webpack.config.js +++ b/packages/core/webpack.config.js @@ -1,47 +1,5 @@ const path = require('path'); -const webpack = require('webpack'); - -var timers = {}; -function generateNewId() { - var r = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); - while (timers.hasOwnProperty(r)) { // check weather the id already exists - r = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); - } - return r; -} - - -function check() { - if (Object.keys(timers).length <= 0) return; - - var t = Date.now(); - for (var timerId in timers) { - if (timers.hasOwnProperty(timerId) && t > timers[timerId].time) { - timers[timerId].callback(); - clearTimeout(timerId); - } - } - requestIdleCallback(check); -} - - -function _setTimeout(callback, delay) { - if (typeof(callback) != 'function') throw new Error("callback should be a function"); - if (typeof(delay) != 'number' || delay < 0) throw new Error("delay should be a positive number"); - var newId = generateNewId(); - timers[newId] = { - callback: callback, - time: Date.now() + delay - }; - if (Object.keys(timers).length == 1) { - requestIdleCallback(check); - } - return newId; -} - -function _clearTimeout(id) { - if (timers.hasOwnProperty(id)) delete timers[id]; -} +const plugins = require('./pack/plugins'); module.exports = { entry: './src/index.ts', @@ -61,11 +19,5 @@ module.exports = { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), }, - plugins: [ - new webpack.DefinePlugin({ - setTimeout: _setTimeout, - clearTimeout: _clearTimeout, - }) - //... - ] + plugins }; \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8daaa76..469283e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: packages/core: dependencies: + '@prisma/client': + specifier: 5.2.0 + version: 5.2.0(prisma@5.2.0) '@types/uuid': specifier: ^8.3.4 version: 8.3.4 @@ -147,10 +150,27 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: false + /@prisma/client@5.2.0(prisma@5.2.0): + resolution: {integrity: sha512-AiTjJwR4J5Rh6Z/9ZKrBBLel3/5DzUNntMohOy7yObVnVoTNVFi2kvpLZlFuKO50d7yDspOtW6XBpiAd0BVXbQ==} + engines: {node: '>=16.13'} + requiresBuild: true + peerDependencies: + prisma: '*' + peerDependenciesMeta: + prisma: + optional: true + dependencies: + '@prisma/engines-version': 5.2.0-25.2804dc98259d2ea960602aca6b8e7fdc03c1758f + prisma: 5.2.0 + dev: false + + /@prisma/engines-version@5.2.0-25.2804dc98259d2ea960602aca6b8e7fdc03c1758f: + resolution: {integrity: sha512-jsnKT5JIDIE01lAeCj2ghY9IwxkedhKNvxQeoyLs6dr4ZXynetD0vTy7u6wMJt8vVPv8I5DPy/I4CFaoXAgbtg==} + dev: false + /@prisma/engines@5.2.0: resolution: {integrity: sha512-dT7FOLUCdZmq+AunLqB1Iz+ZH/IIS1Fz2THmKZQ6aFONrQD/BQ5ecJ7g2wGS2OgyUFf4OaLam6/bxmgdOBDqig==} requiresBuild: true - dev: true /@socket.io/component-emitter@3.1.0: resolution: {integrity: sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==} @@ -871,7 +891,6 @@ packages: requiresBuild: true dependencies: '@prisma/engines': 5.2.0 - dev: true /punycode@2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} diff --git a/scripts/types/database.ts b/scripts/types/database.ts new file mode 100644 index 0000000..b427bc9 --- /dev/null +++ b/scripts/types/database.ts @@ -0,0 +1,15 @@ +export async function webpackDB(pkg_dir: string) { + const migrations: { date: number, sql: string }[] = []; + + const output = +`const webpack = require('webpack'); + +export default new webpack.DefinePlugin({ + database_migrations: { + index: [ ${migrations.map(m => m.date).join(', ')} ], + entries: { +${migrations.map(m => ` ${m.date}: \`${m.sql}\`,`).join('\n')} + } + } +})` +} \ No newline at end of file