@rel-packages/osu-beatmap-parser 0.1.8 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
package/dist/index.d.ts CHANGED
@@ -1,11 +1,4 @@
1
1
  import { OsuKey, OsuInput } from "./types";
2
- export declare function get_property(location: string, key: OsuKey): string;
3
- export declare function get_properties(input: string | OsuInput, keys: OsuKey[]): Record<OsuKey, string> & {
4
- id?: string;
5
- };
6
- export declare function process_beatmaps(inputs: (string | OsuInput)[], keys: OsuKey[]): Promise<(Record<OsuKey, string> & {
7
- id?: string;
8
- })[]>;
9
- export declare function get_duration(location: string): number;
10
- export declare function get_audio_duration(location: string): number;
2
+ export declare const get_property: (data: Uint8Array, key: OsuKey) => any;
3
+ export declare const get_properties: (input: Uint8Array | OsuInput, keys: OsuKey[]) => any;
11
4
  export { OsuKey, OsuInput };
package/dist/index.js CHANGED
@@ -1,46 +1,17 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.get_properties = exports.get_property = void 0;
4
+ const bindings_1 = require("./lib/bindings");
5
+ const get_property = (data, key) => {
6
+ return bindings_1.native.get_property(data, key);
7
+ };
6
8
  exports.get_property = get_property;
7
- exports.get_properties = get_properties;
8
- exports.process_beatmaps = process_beatmaps;
9
- exports.get_duration = get_duration;
10
- exports.get_audio_duration = get_audio_duration;
11
- const node_gyp_build_1 = __importDefault(require("node-gyp-build"));
12
- const path_1 = __importDefault(require("path"));
13
- const native = (0, node_gyp_build_1.default)(path_1.default.join(__dirname, ".."));
14
- function get_property(location, key) {
15
- return native.get_property(location, key);
16
- }
17
- ;
18
- function get_properties(input, keys) {
19
- const location = typeof input === "string" ? input : input.path;
20
- const result = native.get_properties(location, keys);
21
- if (typeof input !== "string" && input.id) {
9
+ const get_properties = (input, keys) => {
10
+ const data = input instanceof Uint8Array ? input : input.data;
11
+ const result = bindings_1.native.get_properties(data, keys);
12
+ if (!(input instanceof Uint8Array) && input.id) {
22
13
  return { ...result, id: input.id };
23
14
  }
24
15
  return result;
25
- }
26
- ;
27
- async function process_beatmaps(inputs, keys) {
28
- const locations = inputs.map(i => typeof i === "string" ? i : i.path);
29
- const results = await native.process_beatmaps(locations, keys);
30
- return results.map((res, i) => {
31
- const input = inputs[i];
32
- if (typeof input !== "string" && input.id) {
33
- return { ...res, id: input.id };
34
- }
35
- return res;
36
- });
37
- }
38
- ;
39
- function get_duration(location) {
40
- return native.get_duration(location);
41
- }
42
- ;
43
- function get_audio_duration(location) {
44
- return native.get_audio_duration(location);
45
- }
46
- ;
16
+ };
17
+ exports.get_properties = get_properties;
@@ -0,0 +1 @@
1
+ export declare let native: any;
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.native = void 0;
4
+ const IS_BROWSER = globalThis.window != undefined;
5
+ const load_native_module = () => {
6
+ if (IS_BROWSER) {
7
+ const wasm_proxy = {
8
+ instance: null,
9
+ get_property: (data, key) => {
10
+ if (wasm_proxy.instance == null) {
11
+ throw Error("WASM not loaded yet");
12
+ }
13
+ const wasm_inst = wasm_proxy.instance;
14
+ const buffer_ptr = wasm_inst._malloc(data.length);
15
+ wasm_inst.HEAPU8.set(data, buffer_ptr);
16
+ const result_val = wasm_inst.get_property(buffer_ptr, data.length, key);
17
+ wasm_inst._free(buffer_ptr);
18
+ return result_val;
19
+ },
20
+ get_properties: (data, keys) => {
21
+ if (wasm_proxy.instance == null) {
22
+ throw Error("WASM not loaded yet");
23
+ }
24
+ const wasm_inst = wasm_proxy.instance;
25
+ const buffer_ptr = wasm_inst._malloc(data.length);
26
+ wasm_inst.HEAPU8.set(data, buffer_ptr);
27
+ const results_obj = wasm_inst.get_properties(buffer_ptr, data.length, keys);
28
+ wasm_inst._free(buffer_ptr);
29
+ return results_obj;
30
+ },
31
+ };
32
+ const create_func = globalThis.create_osu_parser;
33
+ if (create_func != undefined) {
34
+ create_func().then((instance) => {
35
+ wasm_proxy.instance = instance;
36
+ });
37
+ }
38
+ return wasm_proxy;
39
+ }
40
+ try {
41
+ const fs_mod = require("fs");
42
+ const path_mod = require("path");
43
+ const load_prebuilt = () => {
44
+ const OS_PLATFORM = process.platform;
45
+ const CPU_ARCH = process.arch;
46
+ const SCAN_PATHS = [
47
+ path_mod.join(__dirname, "..", "..", "prebuilds", `${OS_PLATFORM}-${CPU_ARCH}`, "osu-beatmap-parser.node"),
48
+ path_mod.join(__dirname, "prebuilds", `${OS_PLATFORM}-${CPU_ARCH}`, "osu-beatmap-parser.node"),
49
+ ];
50
+ for (const path_str of SCAN_PATHS) {
51
+ if (fs_mod.existsSync(path_str)) {
52
+ return require(path_str);
53
+ }
54
+ }
55
+ return false;
56
+ };
57
+ const load_local = () => {
58
+ const SCAN_PATHS = [
59
+ path_mod.join(__dirname, "..", "..", "build", "osu-beatmap-parser.node"),
60
+ path_mod.join(__dirname, "..", "..", "build", "Release", "osu-beatmap-parser.node"),
61
+ path_mod.join(__dirname, "..", "build", "osu-beatmap-parser.node"),
62
+ path_mod.join(__dirname, "build", "osu-beatmap-parser.node"),
63
+ ];
64
+ for (const path_str of SCAN_PATHS) {
65
+ if (fs_mod.existsSync(path_str)) {
66
+ return require(path_str);
67
+ }
68
+ }
69
+ return false;
70
+ };
71
+ const bin_module = load_prebuilt() || load_local();
72
+ if (bin_module) {
73
+ return bin_module;
74
+ }
75
+ }
76
+ catch (e) { }
77
+ return false;
78
+ };
79
+ exports.native = load_native_module();
80
+ try {
81
+ if (exports.native == false && IS_BROWSER == false) {
82
+ throw Error("failed to find native module...");
83
+ }
84
+ }
85
+ catch (err) {
86
+ if (IS_BROWSER) {
87
+ exports.native = {};
88
+ }
89
+ else {
90
+ throw new Error("failed to load native module...\n" + err);
91
+ }
92
+ }
package/dist/types.d.ts CHANGED
@@ -1,12 +1,9 @@
1
1
  export type OsuKey = "AudioFilename" | "AudioLeadIn" | "PreviewTime" | "Countdown" | "SampleSet" | "StackLeniency" | "Mode" | "LetterboxInBreaks" | "WidescreenStoryboard" | "Bookmarks" | "DistanceSpacing" | "BeatDivisor" | "GridSize" | "TimelineZoom" | "Title" | "TitleUnicode" | "Artist" | "ArtistUnicode" | "Creator" | "Version" | "Source" | "Tags" | "BeatmapID" | "BeatmapSetID" | "HPDrainRate" | "CircleSize" | "OverallDifficulty" | "ApproachRate" | "SliderMultiplier" | "SliderTickRate" | "Background" | "Video" | "Storyboard" | "Duration";
2
2
  export interface OsuInput {
3
- path: string;
3
+ data: Uint8Array;
4
4
  id?: string;
5
5
  }
6
6
  export interface INativeExporter {
7
- get_property(location: string, key: string): string;
8
- get_properties(location: string, keys: string[]): Record<string, string>;
9
- process_beatmaps(locations: string[], keys: string[]): Promise<Record<string, string>[]>;
10
- get_duration(location: string): number;
11
- get_audio_duration(location: string): number;
7
+ get_property(data: Uint8Array, key: string): string;
8
+ get_properties(data: Uint8Array, keys: string[]): Record<string, string>;
12
9
  }
package/package.json CHANGED
@@ -1,24 +1,43 @@
1
1
  {
2
2
  "name": "@rel-packages/osu-beatmap-parser",
3
- "version": "0.1.8",
3
+ "version": "1.0.3",
4
4
  "description": ".osu parser for nodejs",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "homepage": "https://github.com/mezleca/osu-beatmap-parser",
8
8
  "scripts": {
9
- "dev": "npm run compile:native && tsx scripts/verify.ts",
10
- "compile": "npm run compile:native && npm run compile:tsc",
9
+ "update:patch": "npm version patch && git push --follow-tags",
10
+ "update:minor": "npm version minor && git push --follow-tags",
11
+ "update:major": "npm version major && git push --follow-tags",
12
+ "prepublishOnly": "npm run compile:tsc && mkdir -p lib",
13
+ "compile:native": "tsx scripts/build.ts native",
14
+ "compile:wasm": "tsx scripts/build.ts wasm",
11
15
  "compile:tsc": "tsc",
12
- "compile:native": "cmake-js build",
13
- "prebuild": "prebuild --backend cmake-js --strip --verbose"
16
+ "build": "tsx scripts/build.ts all && npm run compile:tsc",
17
+ "example:wasm": "bun run compile:wasm && bun run examples/wasm/server.ts",
18
+ "example:node": "bun run compile:native && tsx examples/node/index.ts"
14
19
  },
15
- "keywords": [],
20
+ "keywords": [
21
+ "osu",
22
+ "beatmap",
23
+ "parser",
24
+ "native"
25
+ ],
16
26
  "author": "",
17
27
  "license": "ISC",
18
28
  "repository": {
19
29
  "url": "https://github.com/mezleca/osu-beatmap-parser.git"
20
30
  },
21
31
  "type": "commonjs",
32
+ "files": [
33
+ "dist/",
34
+ "prebuilds/",
35
+ "build/*.node",
36
+ "build/*.wasm",
37
+ "build/*.js",
38
+ "lib/bindings.ts",
39
+ "README.md"
40
+ ],
22
41
  "devDependencies": {
23
42
  "@types/bindings": "^1.5.5",
24
43
  "@types/node": "^24.10.1",
@@ -27,7 +46,6 @@
27
46
  "tsx": "^4.21.0",
28
47
  "typescript": "^5.9.3"
29
48
  },
30
- "dependencies": {
31
- "node-gyp-build": "^4.8.4"
32
- }
33
- }
49
+ "dependencies": {},
50
+ "optionalDependencies": {}
51
+ }
package/.prebuildrc DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "upload": "gh release upload {tag_name} {file_path} --repo={owner}/{repo} --clobber",
3
- "download": "https://github.com/{owner}/{repo}/releases/download/{tag}/{file_name}",
4
- "tag-prefix": "v",
5
- "backend": "cmake-js"
6
- }
package/CMakeLists.txt DELETED
@@ -1,68 +0,0 @@
1
- cmake_minimum_required(VERSION 3.16)
2
-
3
- if(WIN32)
4
- if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
5
- if(EXISTS "${CMAKE_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake")
6
- set(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake")
7
- elseif(EXISTS "C:/vcpkg/scripts/buildsystems/vcpkg.cmake")
8
- set(CMAKE_TOOLCHAIN_FILE "C:/vcpkg/scripts/buildsystems/vcpkg.cmake")
9
- endif()
10
- endif()
11
- set(VCPKG_TARGET_TRIPLET "x64-windows-static")
12
- endif()
13
-
14
- project(osu-beatmap-parser VERSION 0.0.1)
15
-
16
- set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
17
- set(CMAKE_CXX_STANDARD 17)
18
- set(CMAKE_CXX_STANDARD_REQUIRED ON)
19
- set(BUILD_TESTING OFF CACHE BOOL "Build tests" FORCE)
20
- set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries")
21
-
22
- file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "src/native/*.cpp")
23
- file(GLOB_RECURSE HEADERS CONFIGURE_DEPENDS "src/native/*.hpp")
24
-
25
- if(WIN32)
26
- find_package(SndFile CONFIG REQUIRED)
27
- set(SNDFILE_LIBRARIES SndFile::sndfile)
28
- else()
29
- find_package(PkgConfig REQUIRED)
30
- pkg_check_modules(SNDFILE REQUIRED sndfile)
31
- endif()
32
-
33
- execute_process(
34
- COMMAND node -p "require('node-addon-api').include"
35
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
36
- OUTPUT_VARIABLE NODE_ADDON_API_DIR
37
- OUTPUT_STRIP_TRAILING_WHITESPACE
38
- )
39
-
40
- string(REPLACE "\"" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
41
-
42
- add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS} ${CMAKE_JS_SRC})
43
-
44
- set_target_properties(${PROJECT_NAME} PROPERTIES
45
- PREFIX ""
46
- SUFFIX ".node"
47
- CXX_STANDARD 17
48
- CXX_STANDARD_REQUIRED ON
49
- )
50
-
51
- if (MSVC)
52
- set(MSVC_RUNTIME_LIBRARY OFF)
53
- add_compile_definitions(_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING)
54
- execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS})
55
- target_compile_options(${PROJECT_NAME} PRIVATE /Zc:__cplusplus)
56
- endif()
57
-
58
- target_include_directories(${PROJECT_NAME} PRIVATE
59
- ${NODE_ADDON_API_DIR}
60
- ${CMAKE_JS_INC}
61
- ${SNDFILE_INCLUDE_DIRS}
62
- )
63
-
64
- target_link_libraries(
65
- ${PROJECT_NAME}
66
- ${CMAKE_JS_LIB}
67
- ${SNDFILE_LIBRARIES}
68
- )
@@ -1,265 +0,0 @@
1
- #include <filesystem>
2
- #include <napi.h>
3
- #include <iostream>
4
- #include <sndfile.h>
5
- #include <string>
6
- #include <thread>
7
- #include <fstream>
8
- #include <vector>
9
- #include <atomic>
10
- #include "osu/parser.hpp"
11
- #include "osu/audio.hpp"
12
- #include "addon.hpp"
13
- #include "pool.hpp"
14
-
15
- #define NOOP_FUNC(env) Napi::Function::New(env, [](const Napi::CallbackInfo& info){})
16
-
17
- AudioAnalyzer audio_analizer;
18
-
19
- std::filesystem::path dirname(const std::string &path) {
20
- std::filesystem::path p(path);
21
- return p.parent_path();
22
- }
23
-
24
- std::string read_file(const std::string& path) {
25
- std::ifstream file(path, std::ios::binary | std::ios::ate);
26
-
27
- if (!file.is_open()) {
28
- return "";
29
- }
30
-
31
- std::streamsize size = file.tellg();
32
- file.seekg(0, std::ios::beg);
33
-
34
- std::string buffer(size, ' ');
35
-
36
- if (file.read(buffer.data(), size)) {
37
- return buffer;
38
- }
39
-
40
- return "";
41
- }
42
-
43
- Napi::Value ParserAddon::get_property(const Napi::CallbackInfo& info) {
44
- if (info.Length() < 2) {
45
- return Napi::String::New(info.Env(), "");
46
- }
47
-
48
- if (!info[0].IsString() || !info[1].IsString()) {
49
- return Napi::String::New(info.Env(), "");
50
- }
51
-
52
- std::string location = info[0].As<Napi::String>().Utf8Value();
53
- std::string key = info[1].As<Napi::String>().Utf8Value();
54
- std::string content = read_file(location);
55
-
56
- if (content.empty()) {
57
- return Napi::String::New(info.Env(), "");
58
- }
59
-
60
- return Napi::String::From(info.Env(), osu_parser::get_property(content, key));
61
- }
62
-
63
- Napi::Value ParserAddon::get_properties(const Napi::CallbackInfo& info) {
64
- if (info.Length() < 2) {
65
- return Napi::Object::New(info.Env());
66
- }
67
-
68
- std::string location = info[0].As<Napi::String>().Utf8Value();
69
- Napi::Array keys_array = info[1].As<Napi::Array>();
70
-
71
- std::vector<std::string> keys;
72
-
73
- for (uint32_t i = 0; i < keys_array.Length(); i++) {
74
- Napi::Value val = keys_array[i];
75
- if (val.IsString()) {
76
- keys.push_back(val.As<Napi::String>().Utf8Value());
77
- }
78
- }
79
-
80
- std::string content = read_file(location);
81
-
82
- if (content.empty()) {
83
- return Napi::Object::New(info.Env());
84
- }
85
-
86
- auto results = osu_parser::get_properties(content, keys);
87
-
88
- Napi::Object obj = Napi::Object::New(info.Env());
89
-
90
- for (const auto& [k, v] : results) {
91
- obj.Set(k, v);
92
- }
93
-
94
- return obj;
95
- }
96
-
97
- struct BatchContext {
98
- std::vector<std::string> paths;
99
- std::vector<std::string> keys;
100
- std::vector<std::unordered_map<std::string, std::string>> results;
101
- std::atomic<size_t> completed_count{0};
102
- Napi::ThreadSafeFunction tsfn;
103
- Napi::Promise::Deferred deferred;
104
- bool needs_duration = false;
105
-
106
- BatchContext(Napi::Env env) : deferred(Napi::Promise::Deferred::New(env)) {}
107
- };
108
-
109
- void process_chunk(BatchContext* context, size_t start, size_t end) {
110
- for (size_t i = start; i < end; i++) {
111
- std::string content = read_file(context->paths[i]);
112
- if (!content.empty()) {
113
- context->results[i] = osu_parser::get_properties(content, context->keys);
114
-
115
- if (context->needs_duration) {
116
- std::string audio_file_name = osu_parser::get_property(content, "AudioFilename");
117
- if (!audio_file_name.empty()) {
118
- std::filesystem::path audio_path = dirname(context->paths[i]) / audio_file_name;
119
- double duration = audio_analizer.get_audio_duration(audio_path.string());
120
- context->results[i]["Duration"] = std::to_string(duration);
121
- }
122
- }
123
- }
124
- }
125
-
126
- size_t completed = context->completed_count.fetch_add(end - start) + (end - start);
127
-
128
- if (completed == context->paths.size()) {
129
- auto callback = [context](Napi::Env env, Napi::Function jsCallback) {
130
- Napi::Array result_array = Napi::Array::New(env, context->results.size());
131
-
132
- for (size_t i = 0; i < context->results.size(); i++) {
133
- Napi::Object obj = Napi::Object::New(env);
134
- for (const auto& [k, v] : context->results[i]) {
135
- obj.Set(k, v);
136
- }
137
- result_array[i] = obj;
138
- }
139
-
140
- context->deferred.Resolve(result_array);
141
- };
142
-
143
- context->tsfn.BlockingCall(callback);
144
- context->tsfn.Release();
145
- }
146
- }
147
-
148
- Napi::Value ParserAddon::process_beatmaps(const Napi::CallbackInfo& info) {
149
- Napi::Env env = info.Env();
150
-
151
- if (info.Length() < 2) {
152
- auto deferred = Napi::Promise::Deferred::New(env);
153
- deferred.Reject(Napi::String::New(env, "Invalid arguments"));
154
- return deferred.Promise();
155
- }
156
-
157
- Napi::Array paths_array = info[0].As<Napi::Array>();
158
- Napi::Array keys_array = info[1].As<Napi::Array>();
159
-
160
- auto context = new BatchContext(env);
161
-
162
- for (uint32_t i = 0; i < paths_array.Length(); i++) {
163
- context->paths.push_back(Napi::Value(paths_array[i]).As<Napi::String>().Utf8Value());
164
- }
165
-
166
- for (uint32_t i = 0; i < keys_array.Length(); i++) {
167
- std::string key = Napi::Value(keys_array[i]).As<Napi::String>().Utf8Value();
168
- context->keys.push_back(key);
169
- if (key == "Duration") {
170
- context->needs_duration = true;
171
- }
172
- }
173
-
174
- context->results.resize(context->paths.size());
175
-
176
- context->tsfn = Napi::ThreadSafeFunction::New(
177
- env,
178
- NOOP_FUNC(env),
179
- "ProcessBeatmaps",
180
- 0,
181
- 1,
182
- [context](Napi::Env) {
183
- delete context;
184
- }
185
- );
186
-
187
- size_t total_files = context->paths.size();
188
- size_t thread_count = std::thread::hardware_concurrency();
189
-
190
- if (thread_count == 0) {
191
- thread_count = 1;
192
- }
193
-
194
- size_t chunk_size = (total_files + thread_count - 1) / thread_count;
195
-
196
- for (size_t t = 0; t < thread_count; t++) {
197
- size_t start = t * chunk_size;
198
- size_t end = std::min(start + chunk_size, total_files);
199
-
200
- if (start >= end) {
201
- break;
202
- }
203
-
204
- pool.enqueue([context, start, end]() {
205
- process_chunk(context, start, end);
206
- });
207
- }
208
-
209
- return context->deferred.Promise();
210
- }
211
-
212
- Napi::Value ParserAddon::get_duration(const Napi::CallbackInfo& info) {
213
- if (info.Length() < 1) {
214
- return Napi::Number::New(info.Env(), 0.0);
215
- }
216
-
217
- if (!info[0].IsString()) {
218
- return Napi::String::New(info.Env(), "");
219
- }
220
-
221
- std::string location = info[0].As<Napi::String>().Utf8Value();
222
- std::string content = read_file(location);
223
-
224
- if (content.empty()) {
225
- return Napi::Number::New(info.Env(), 0.0);
226
- }
227
-
228
- std::string audio_file_name = osu_parser::get_property(content, "AudioFilename");
229
- std::filesystem::path audio_path = dirname(location) / audio_file_name;
230
-
231
- return Napi::Number::From(info.Env(), audio_analizer.get_audio_duration(audio_path.string()));
232
- }
233
-
234
- Napi::Value ParserAddon::get_audio_duration(const Napi::CallbackInfo& info) {
235
- if (info.Length() < 1) {
236
- return Napi::Number::New(info.Env(), 0.0);
237
- }
238
-
239
- if (!info[0].IsString()) {
240
- return Napi::String::New(info.Env(), "");
241
- }
242
-
243
- std::string location = info[0].As<Napi::String>().Utf8Value();
244
- std::filesystem::path audio_path(location);
245
-
246
- return Napi::Number::From(info.Env(), audio_analizer.get_audio_duration(audio_path.string()));
247
- }
248
-
249
- Napi::Value ParserAddon::test_promise(const Napi::CallbackInfo& info) {
250
- auto deffered = Napi::Promise::Deferred::New(info.Env());
251
- auto tsfn = Napi::ThreadSafeFunction::New(info.Env(), NOOP_FUNC(info.Env()), "tsfn", 0, 1);
252
-
253
- std::thread([tsfn, deffered]() {
254
- tsfn.NonBlockingCall([deffered](Napi::Env env, Napi::Function) {
255
- std::this_thread::sleep_for(std::chrono::milliseconds(2000));
256
- deffered.Resolve(Napi::Boolean::New(env, true));
257
- });
258
-
259
- tsfn.Release();
260
- }).detach();
261
-
262
- return deffered.Promise();
263
- }
264
-
265
- NODE_API_ADDON(ParserAddon)
@@ -1,26 +0,0 @@
1
- #pragma once
2
-
3
- #include <napi.h>
4
- #include "pool.hpp"
5
-
6
- class ParserAddon : public Napi::Addon<ParserAddon> {
7
- public:
8
- ParserAddon(Napi::Env env, Napi::Object exports) {
9
- pool.initialize(std::thread::hardware_concurrency());
10
- DefineAddon(exports, {
11
- InstanceMethod("get_property", &ParserAddon::get_property),
12
- InstanceMethod("get_properties", &ParserAddon::get_properties),
13
- InstanceMethod("process_beatmaps", &ParserAddon::process_beatmaps),
14
- InstanceMethod("get_duration", &ParserAddon::get_duration),
15
- InstanceMethod("get_audio_duration", &ParserAddon::get_audio_duration),
16
- InstanceMethod("test_promise", &ParserAddon::test_promise)
17
- });
18
- }
19
-
20
- Napi::Value get_property(const Napi::CallbackInfo& info);
21
- Napi::Value get_properties(const Napi::CallbackInfo& info);
22
- Napi::Value process_beatmaps(const Napi::CallbackInfo& info);
23
- Napi::Value get_duration(const Napi::CallbackInfo& info);
24
- Napi::Value get_audio_duration(const Napi::CallbackInfo& info);
25
- Napi::Value test_promise(const Napi::CallbackInfo& info);
26
- };
@@ -1,56 +0,0 @@
1
- #pragma once
2
- #include <string>
3
- #include <unordered_set>
4
- #include <unordered_map>
5
-
6
- enum OSU_SECTIONS {
7
- General = 0,
8
- Editor,
9
- Metadata,
10
- Difficulty,
11
- Events,
12
- TimingPoints,
13
- Colours,
14
- HitObjects
15
- };
16
-
17
- const std::unordered_map<std::string_view, std::string_view> KEY_TO_SECTION = {
18
- {"AudioFilename", "[General]"},
19
- {"AudioLeadIn", "[General]"},
20
- {"PreviewTime", "[General]"},
21
- {"Countdown", "[General]"},
22
- {"SampleSet", "[General]"},
23
- {"StackLeniency", "[General]"},
24
- {"Mode", "[General]"},
25
- {"LetterboxInBreaks", "[General]"},
26
- {"WidescreenStoryboard", "[General]"},
27
- {"Bookmarks", "[Editor]"},
28
- {"DistanceSpacing", "[Editor]"},
29
- {"BeatDivisor", "[Editor]"},
30
- {"GridSize", "[Editor]"},
31
- {"TimelineZoom", "[Editor]"},
32
- {"Title", "[Metadata]"},
33
- {"TitleUnicode", "[Metadata]"},
34
- {"Artist", "[Metadata]"},
35
- {"ArtistUnicode", "[Metadata]"},
36
- {"Creator", "[Metadata]"},
37
- {"Version", "[Metadata]"},
38
- {"Source", "[Metadata]"},
39
- {"Tags", "[Metadata]"},
40
- {"BeatmapID", "[Metadata]"},
41
- {"BeatmapSetID", "[Metadata]"},
42
- {"HPDrainRate", "[Difficulty]"},
43
- {"CircleSize", "[Difficulty]"},
44
- {"OverallDifficulty", "[Difficulty]"},
45
- {"ApproachRate", "[Difficulty]"},
46
- {"SliderMultiplier", "[Difficulty]"},
47
- {"SliderTickRate", "[Difficulty]"},
48
- // special ones (doenst have keys)
49
- {"Background", "[Events]"},
50
- {"Video", "[Events]"},
51
- {"Storyboard", "[Events]"},
52
- // extra special ones (why not)
53
- {"Duration", "[General]"}
54
- };
55
-
56
- const std::unordered_set<std::string_view> SPECIAL_KEYS {"Background", "Video", "Storyboard"};