Skip to content

Commit

Permalink
Merge pull request #1251 from demergent-labs/functional_syntax_audio_…
Browse files Browse the repository at this point in the history
…recorder

Functional syntax audio recorder
  • Loading branch information
lastmjs authored Sep 23, 2023
2 parents 303f71b + 43b6dff commit c9cce30
Show file tree
Hide file tree
Showing 20 changed files with 634 additions and 496 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
# The check-basic-integration-tests-success job is designed to ensure that all jobs spun up from the matrix in the basic-integration-tests have succeeded

# All Examples TODO restore when https://github.com/demergent-labs/azle/issues/1192 is resolved
# "examples/audio_recorder",
# "examples/bitcoin",
# "examples/blob_array",
# "examples/bytes",
Expand Down Expand Up @@ -66,7 +65,6 @@
# "examples/robust_imports",
# "examples/run_time_errors",
# "examples/rust_type_conversions",
# "examples/service",
# "examples/stable_structures",
# "examples/tuple_types",

Expand Down Expand Up @@ -115,10 +113,12 @@ jobs:
EXAMPLE_DIRECTORIES=$(cat << END
[
"examples/async_await",
"examples/audio_recorder",
"examples/primitive_types",
"examples/principal",
"examples/query",
"examples/randomness",
"examples/service",
"examples/simple_erc20",
"examples/simple_user_accounts",
"examples/stable_memory",
Expand Down
9 changes: 3 additions & 6 deletions canisters/management/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { blob, Principal, Service, update } from '../../src/lib_functional';

export const managementCanister = Service(
{
raw_rand: update([], blob)
},
Principal.fromText('aaaaa-aa')
);
export const managementCanister = Service({
raw_rand: update([], blob)
})(Principal.fromText('aaaaa-aa'));
28 changes: 14 additions & 14 deletions examples/audio_recorder/src/index.did
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
type rec_0 = record {id:principal; username:text; recordingIds:vec principal; createdAt:nat64};
type rec_1 = record {id:principal; username:text; recordingIds:vec principal; createdAt:nat64};
type rec_2 = record {id:principal; username:text; recordingIds:vec principal; createdAt:nat64};
type rec_3 = record {id:principal; username:text; recordingIds:vec principal; createdAt:nat64};
type rec_4 = variant {RecordingDoesNotExist:principal; UserDoesNotExist:principal};
type rec_5 = record {id:principal; audio:vec nat8; userId:principal; name:text; createdAt:nat64};
type rec_4 = record {id:principal; username:text; recordingIds:vec principal; createdAt:nat64};
type rec_5 = record {id:principal; username:text; recordingIds:vec principal; createdAt:nat64};
type rec_6 = variant {RecordingDoesNotExist:principal; UserDoesNotExist:principal};
type rec_7 = record {id:principal; audio:vec nat8; userId:principal; name:text; createdAt:nat64};
type rec_8 = record {id:principal; audio:vec nat8; userId:principal; name:text; createdAt:nat64};
type rec_8 = variant {RecordingDoesNotExist:principal; UserDoesNotExist:principal};
type rec_9 = record {id:principal; audio:vec nat8; userId:principal; name:text; createdAt:nat64};
type rec_10 = variant {RecordingDoesNotExist:principal; UserDoesNotExist:principal};
type rec_10 = record {id:principal; audio:vec nat8; userId:principal; name:text; createdAt:nat64};
type rec_11 = record {id:principal; audio:vec nat8; userId:principal; name:text; createdAt:nat64};
type rec_12 = variant {RecordingDoesNotExist:principal; UserDoesNotExist:principal};
service: () -> {
createUser: (text) -> (rec_0);
readUsers: () -> (vec rec_1) query;
readUserById: (principal) -> (opt rec_2) query;
deleteUser: (principal) -> (variant {Ok:rec_3; Err:rec_4});
createRecording: (vec nat8, text, principal) -> (variant {Ok:rec_5; Err:rec_6});
readRecordings: () -> (vec rec_7) query;
readRecordingById: (principal) -> (opt rec_8) query;
deleteRecording: (principal) -> (variant {Ok:rec_9; Err:rec_10});
createUser: (text) -> (rec_2);
readUsers: () -> (vec rec_3) query;
readUserById: (principal) -> (opt rec_4) query;
deleteUser: (principal) -> (variant {Ok:rec_5; Err:rec_6});
createRecording: (vec nat8, text, principal) -> (variant {Ok:rec_7; Err:rec_8});
readRecordings: () -> (vec rec_9) query;
readRecordingById: (principal) -> (opt rec_10) query;
deleteRecording: (principal) -> (variant {Ok:rec_11; Err:rec_12});
}
266 changes: 116 additions & 150 deletions examples/audio_recorder/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
blob,
candid,
ic,
nat64,
Opt,
Expand All @@ -17,194 +16,161 @@ import {
Vec
} from 'azle';

class User extends Record {
@candid(principal)
id: Principal;

@candid(nat64)
createdAt: nat64;

@candid(Vec(principal))
recordingIds: Vec<Principal>;

@candid(text)
username: text;
}

class Recording extends Record {
@candid(principal)
id: Principal;

@candid(blob)
audio: blob;

@candid(nat64)
createdAt: nat64;

@candid(text)
name: text;

@candid(principal)
userId: Principal;
}

class AudioRecorderError extends Variant {
@candid(principal)
RecordingDoesNotExist: Principal;

@candid(principal)
UserDoesNotExist: Principal;
}

export default class extends Service {
users = new StableBTreeMap<Principal, User>(principal, User as any, 0);
recordings = new StableBTreeMap<Principal, Recording>(
principal,
Recording as any,
1
);

@update([text], User)
createUser(username: text): User {
const User = Record({
id: principal,
createdAt: nat64,
recordingIds: Vec(principal),
username: text
});

const Recording = Record({
id: principal,
audio: blob,
createdAt: nat64,
name: text,
userId: principal
});

const AudioRecorderError = Variant({
RecordingDoesNotExist: principal,
UserDoesNotExist: principal
});

let users = StableBTreeMap(principal, User, 0);
let recordings = StableBTreeMap(principal, Recording, 1);

export default Service({
createUser: update([text], User, (username) => {
const id = generateId();
const user: User = {
const user: typeof User = {
id,
createdAt: ic.time(),
recordingIds: [],
username
};

this.users.insert(user.id, user);
users.insert(user.id, user);

return user;
}

@query([], Vec(User))
readUsers(): Vec<User> {
return this.users.values();
}

@query([principal], Opt(User))
readUserById(id: Principal): Opt<User> {
return this.users.get(id);
}

@update([principal], Result(User, AudioRecorderError))
deleteUser(id: Principal): Result<User, AudioRecorderError> {
const userOpt = this.users.get(id);
}),
readUsers: query([], Vec(User), () => {
return users.values();
}),
readUserById: query([principal], Opt(User), (id) => {
return users.get(id);
}),
deleteUser: update([principal], Result(User, AudioRecorderError), (id) => {
const userOpt = users.get(id);

if (userOpt.length === 0) {
return {
Err: AudioRecorderError.create({
Err: {
UserDoesNotExist: id
})
}
};
}

const user = userOpt[0];

user.recordingIds.forEach((recordingId) => {
this.recordings.remove(recordingId);
recordings.remove(recordingId);
});

this.users.remove(user.id);
users.remove(user.id);

return {
Ok: user
};
}

@update([blob, text, principal], Result(Recording, AudioRecorderError))
createRecording(
audio: blob,
name: text,
userId: Principal
): Result<Recording, AudioRecorderError> {
const userOpt = this.users.get(userId);

if (userOpt.length === 0) {
return {
Err: AudioRecorderError.create({
UserDoesNotExist: userId
})
}),
createRecording: update(
[blob, text, principal],
Result(Recording, AudioRecorderError),
(audio: blob, name: text, userId: Principal) => {
const userOpt = users.get(userId);

if (userOpt.length === 0) {
return {
Err: {
UserDoesNotExist: userId
}
};
}

const user = userOpt[0];

const id = generateId();
const recording: typeof Recording = {
id,
audio,
createdAt: ic.time(),
name,
userId
};
}

const user = userOpt[0];

const id = generateId();
const recording: Recording = {
id,
audio,
createdAt: ic.time(),
name,
userId
};

this.recordings.insert(recording.id, recording);

const updatedUser: User = {
...user,
recordingIds: [...user.recordingIds, recording.id]
};
recordings.insert(recording.id, recording);

this.users.insert(updatedUser.id, updatedUser);

return {
Ok: recording
};
}

@query([], Vec(Recording))
readRecordings(): Vec<Recording> {
return this.recordings.values();
}

@query([principal], Opt(Recording))
readRecordingById(id: Principal): Opt<Recording> {
return this.recordings.get(id);
}
const updatedUser: typeof User = {
...user,
recordingIds: [...user.recordingIds, recording.id]
};

@update([principal], Result(Recording, AudioRecorderError))
deleteRecording(id: Principal): Result<Recording, AudioRecorderError> {
const recordingOpt = this.recordings.get(id);
users.insert(updatedUser.id, updatedUser);

if (recordingOpt.length === 0) {
return {
Err: AudioRecorderError.create({ RecordingDoesNotExist: id })
Ok: recording
};
}
),
readRecordings: query([], Vec(Recording), () => {
return recordings.values();
}),
readRecordingById: query([principal], Opt(Recording), (id) => {
return recordings.get(id);
}),
deleteRecording: update(
[principal],
Result(Recording, AudioRecorderError),
(id) => {
const recordingOpt = recordings.get(id);

if (recordingOpt.length === 0) {
return {
Err: { RecordingDoesNotExist: id }
};
}

const recording = recordingOpt[0];

const userOpt = users.get(recording.userId);

if (userOpt.length === 0) {
return {
Err: {
UserDoesNotExist: recording.userId
}
};
}

const user = userOpt[0];

const updatedUser: typeof User = {
...user,
recordingIds: user.recordingIds.filter(
(recordingId) =>
recordingId.toText() !== recording.id.toText()
)
};

const recording = recordingOpt[0];
users.insert(updatedUser.id, updatedUser);

const userOpt = this.users.get(recording.userId);
recordings.remove(id);

if (userOpt.length === 0) {
return {
Err: AudioRecorderError.create({
UserDoesNotExist: recording.userId
})
Ok: recording
};
}

const user = userOpt[0];

const updatedUser: User = {
...user,
recordingIds: user.recordingIds.filter(
(recordingId) => recordingId.toText() !== recording.id.toText()
)
};

this.users.insert(updatedUser.id, updatedUser);

this.recordings.remove(id);

return {
Ok: recording
};
}
}
)
});

function generateId(): Principal {
const randomBytes = new Array(29)
Expand Down
Loading

0 comments on commit c9cce30

Please sign in to comment.