Skip to content

Commit 20f2e41

Browse files
authored
Propagate dependencies in FetchKey. (#368)
1 parent 521a60e commit 20f2e41

File tree

2 files changed

+127
-127
lines changed

2 files changed

+127
-127
lines changed

Examples/RemindersTests/SearchRemindersTests.swift

Lines changed: 105 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -28,101 +28,95 @@ extension BaseTestSuite {
2828
model.searchText = "Take"
2929
try await model.searchTask?.value
3030
#expect(model.searchResults.completedCount == 1)
31-
withKnownIssue(
32-
"'@Fetch' introduces an escaping closure and loses the task-local dependency"
33-
) {
34-
assertInlineSnapshot(of: model.searchResults.rows, as: .customDump) {
35-
"""
36-
[
37-
[0]: SearchRemindersModel.Row(
38-
isPastDue: false,
31+
assertInlineSnapshot(of: model.searchResults.rows, as: .customDump) {
32+
"""
33+
[
34+
[0]: SearchRemindersModel.Row(
35+
isPastDue: false,
36+
notes: "",
37+
reminder: Reminder(
38+
id: UUID(00000000-0000-0000-0000-00000000000A),
39+
dueDate: Date(2009-02-17T23:31:30.000Z),
40+
isFlagged: false,
3941
notes: "",
40-
reminder: Reminder(
41-
id: UUID(00000000-0000-0000-0000-00000000000A),
42-
dueDate: Date(2009-02-17T23:31:30.000Z),
43-
isCompleted: false,
44-
isFlagged: false,
45-
notes: "",
46-
position: 8,
47-
priority: .high,
48-
remindersListID: UUID(00000000-0000-0000-0000-000000000001),
49-
title: "Take out trash"
50-
),
51-
remindersList: RemindersList(
52-
id: UUID(00000000-0000-0000-0000-000000000001),
53-
color: 3985191935,
54-
position: 2,
55-
title: "Family"
56-
),
57-
tags: "",
58-
title: "**Take** out trash"
59-
)
60-
]
61-
"""
62-
}
42+
position: 8,
43+
priority: .high,
44+
remindersListID: UUID(00000000-0000-0000-0000-000000000001),
45+
status: .incomplete,
46+
title: "Take out trash"
47+
),
48+
remindersList: RemindersList(
49+
id: UUID(00000000-0000-0000-0000-000000000001),
50+
color: 3985191935,
51+
position: 2,
52+
title: "Family"
53+
),
54+
tags: "",
55+
title: "**Take** out trash"
56+
)
57+
]
58+
"""
6359
}
6460
}
6561

6662
@Test func showCompleted() async throws {
6763
let model = SearchRemindersModel()
6864
model.searchText = "Take"
6965
try await model.showCompletedButtonTapped()
66+
try await model.searchTask?.value
67+
try await model.$searchResults.load()
7068

71-
withKnownIssue(
72-
"'@Fetch' introduces an escaping closure and loses the task-local dependency"
73-
) {
74-
assertInlineSnapshot(of: model.searchResults.rows, as: .customDump) {
75-
"""
76-
[
77-
[0]: SearchRemindersModel.Row(
78-
isPastDue: false,
69+
assertInlineSnapshot(of: model.searchResults.rows, as: .customDump) {
70+
"""
71+
[
72+
[0]: SearchRemindersModel.Row(
73+
isPastDue: false,
74+
notes: "",
75+
reminder: Reminder(
76+
id: UUID(00000000-0000-0000-0000-00000000000A),
77+
dueDate: Date(2009-02-17T23:31:30.000Z),
78+
isFlagged: false,
7979
notes: "",
80-
reminder: Reminder(
81-
id: UUID(00000000-0000-0000-0000-00000000000A),
82-
dueDate: Date(2009-02-17T23:31:30.000Z),
83-
isCompleted: false,
84-
isFlagged: false,
85-
notes: "",
86-
position: 8,
87-
priority: .high,
88-
remindersListID: UUID(00000000-0000-0000-0000-000000000001),
89-
title: "Take out trash"
90-
),
91-
remindersList: RemindersList(
92-
id: UUID(00000000-0000-0000-0000-000000000001),
93-
color: 3985191935,
94-
position: 2,
95-
title: "Family"
96-
),
97-
tags: "",
98-
title: "**Take** out trash"
80+
position: 8,
81+
priority: .high,
82+
remindersListID: UUID(00000000-0000-0000-0000-000000000001),
83+
status: .incomplete,
84+
title: "Take out trash"
85+
),
86+
remindersList: RemindersList(
87+
id: UUID(00000000-0000-0000-0000-000000000001),
88+
color: 3985191935,
89+
position: 2,
90+
title: "Family"
9991
),
100-
[1]: SearchRemindersModel.Row(
101-
isPastDue: false,
92+
tags: "",
93+
title: "**Take** out trash"
94+
),
95+
[1]: SearchRemindersModel.Row(
96+
isPastDue: false,
97+
notes: "",
98+
reminder: Reminder(
99+
id: UUID(00000000-0000-0000-0000-000000000006),
100+
dueDate: Date(2008-08-07T23:31:30.000Z),
101+
isFlagged: false,
102102
notes: "",
103-
reminder: Reminder(
104-
id: UUID(00000000-0000-0000-0000-000000000006),
105-
dueDate: Date(2008-08-07T23:31:30.000Z),
106-
isCompleted: true,
107-
isFlagged: false,
108-
notes: "",
109-
position: 4,
110-
priority: nil,
111-
remindersListID: UUID(00000000-0000-0000-0000-000000000000),
112-
title: "Take a walk"
113-
),
114-
remindersList: RemindersList(
115-
id: UUID(00000000-0000-0000-0000-000000000000),
116-
color: 1218047999,
117-
position: 1,
118-
title: "Personal"
119-
),
120-
tags: "#car #kids #social",
121-
title: "**Take** a walk"
122-
)
123-
]
124-
"""
125-
}
103+
position: 4,
104+
priority: nil,
105+
remindersListID: UUID(00000000-0000-0000-0000-000000000000),
106+
status: .completed,
107+
title: "Take a walk"
108+
),
109+
remindersList: RemindersList(
110+
id: UUID(00000000-0000-0000-0000-000000000000),
111+
color: 1218047999,
112+
position: 1,
113+
title: "Personal"
114+
),
115+
tags: "#car #kids #social",
116+
title: "**Take** a walk"
117+
)
118+
]
119+
"""
126120
}
127121
}
128122

@@ -131,40 +125,37 @@ extension BaseTestSuite {
131125
model.searchText = "Take"
132126
try await model.showCompletedButtonTapped()
133127
model.deleteCompletedReminders()
128+
try await model.searchTask?.value
134129
try await model.$searchResults.load()
135130
#expect(model.searchResults.completedCount == 0)
136-
withKnownIssue(
137-
"'@Fetch' introduces an escaping closure and loses the task-local dependency"
138-
) {
139-
assertInlineSnapshot(of: model.searchResults.rows, as: .customDump) {
140-
"""
141-
[
142-
[0]: SearchRemindersModel.Row(
143-
isPastDue: false,
131+
assertInlineSnapshot(of: model.searchResults.rows, as: .customDump) {
132+
"""
133+
[
134+
[0]: SearchRemindersModel.Row(
135+
isPastDue: false,
136+
notes: "",
137+
reminder: Reminder(
138+
id: UUID(00000000-0000-0000-0000-00000000000A),
139+
dueDate: Date(2009-02-17T23:31:30.000Z),
140+
isFlagged: false,
144141
notes: "",
145-
reminder: Reminder(
146-
id: UUID(00000000-0000-0000-0000-00000000000A),
147-
dueDate: Date(2009-02-17T23:31:30.000Z),
148-
isCompleted: false,
149-
isFlagged: false,
150-
notes: "",
151-
position: 8,
152-
priority: .high,
153-
remindersListID: UUID(00000000-0000-0000-0000-000000000001),
154-
title: "Take out trash"
155-
),
156-
remindersList: RemindersList(
157-
id: UUID(00000000-0000-0000-0000-000000000001),
158-
color: 3985191935,
159-
position: 2,
160-
title: "Family"
161-
),
162-
tags: "",
163-
title: "**Take** out trash"
164-
)
165-
]
166-
"""
167-
}
142+
position: 8,
143+
priority: .high,
144+
remindersListID: UUID(00000000-0000-0000-0000-000000000001),
145+
status: .incomplete,
146+
title: "Take out trash"
147+
),
148+
remindersList: RemindersList(
149+
id: UUID(00000000-0000-0000-0000-000000000001),
150+
color: 3985191935,
151+
position: 2,
152+
title: "Family"
153+
),
154+
tags: "",
155+
title: "**Take** out trash"
156+
)
157+
]
158+
"""
168159
}
169160
}
170161
}

Sources/SQLiteData/Internal/FetchKey.swift

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ struct FetchKey<Value: Sendable>: SharedReaderKey {
5353
#if DEBUG
5454
let isDefaultDatabase: Bool
5555
#endif
56+
@Dependency(\.self) var dependencies
5657

5758
public typealias ID = FetchKeyID
5859

@@ -86,18 +87,22 @@ struct FetchKey<Value: Sendable>: SharedReaderKey {
8687
return
8788
}
8889
let scheduler: any ValueObservationScheduler = scheduler ?? ImmediateScheduler()
89-
database.asyncRead { dbResult in
90-
let result = dbResult.flatMap { db in
91-
Result {
92-
try request.fetch(db)
90+
withEscapedDependencies { dependencies in
91+
database.asyncRead { dbResult in
92+
let result = dbResult.flatMap { db in
93+
Result {
94+
try dependencies.yield {
95+
try request.fetch(db)
96+
}
97+
}
9398
}
94-
}
95-
scheduler.schedule {
96-
switch result {
97-
case .success(let value):
98-
continuation.resume(returning: value)
99-
case .failure(let error):
100-
continuation.resume(throwing: error)
99+
scheduler.schedule {
100+
switch result {
101+
case .success(let value):
102+
continuation.resume(returning: value)
103+
case .failure(let error):
104+
continuation.resume(throwing: error)
105+
}
101106
}
102107
}
103108
}
@@ -111,8 +116,12 @@ struct FetchKey<Value: Sendable>: SharedReaderKey {
111116
return SharedSubscription {}
112117
}
113118
#endif
114-
let observation = ValueObservation.tracking { db in
115-
Result { try request.fetch(db) }
119+
let observation = withEscapedDependencies { dependencies in
120+
ValueObservation.tracking { db in
121+
dependencies.yield {
122+
Result { try request.fetch(db) }
123+
}
124+
}
116125
}
117126

118127
let scheduler: any ValueObservationScheduler = scheduler ?? ImmediateScheduler()

0 commit comments

Comments
 (0)